UVA 10635

回头看了看LCS。做了几道水题,被一道题的时间给卡住了

题目:UVA10635
用常规的LCS做法做,怎么都超时间,想了想,一共62500那么大,n^2的时间复杂度确实是太高了,看了下白书,发现用LIS的方式很简单就能做出来,而且因为每个数字不一样,时间复杂度降低到了nlogn的复杂的。
思路大概就是因为要用LIS,所以需要有序,我们思考一下怎么才能有序呢,输入的顺序就是有序的,那么我们把输入顺序作为一个数组来考虑。
第二行输入的时候,就可以查询上一个,以输入顺序作为值的数组,查看是否有值,有的话表明能够对上,所以再进行LIS的操作就行了。
算法主要是因为,变得有序了,所以能够二分查看答案,这样就降低了复杂度。
代码如下:

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#define up(i,a,b)  for(int i=a;i<b;i++)
#define dw(i,a,b)  for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
const double esp = 1e-6;
const double pi = acos(-1.0);
const long long INF = 0x3f3f3f3f;
using namespace std;
int t;
int n, p, q;
int vis[1000005];
int sc[1000005];
int dp[1000005];
int main()
{
 cin >> t;
 up(i, 0, t)
 {
  cin >> n >> p >> q;
  memset(vis, -1, sizeof(vis));
  memset(dp, -1, sizeof(dp));
  upd(j, 0, p)
  {
   scanf("%d", &sc[j]);
   vis[sc[j]] = j;
  }
  upd(j, 0, q)
  {
   scanf("%d", &sc[j]);
   sc[j] = vis[sc[j]];
  }
  int top = 1;
  upd(j, 0, q)
  {
   if (sc[j] == -1) continue;
   if (sc[j] > dp[top-1])
   {
    dp[top++] = sc[j];
    //cout << "top" << top<<"dp"<<dp[top-1] << endl;
   }
   else
   {
    int lf = 0, rt = top;
    while (lf <= rt)
    {
     int mid = (lf + rt) >> 1;
     if (sc[j] > dp[mid])
     {
      lf = mid + 1;
      continue;
     }
     else
     {
      rt = mid - 1;
      continue;
     }
    }
    dp[lf] = sc[j];
   }
  }
  printf("Case %d: ", i + 1);
  cout << top-1 << endl;
 }
 return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值