Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 947 Accepted Submission(s): 453
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <cmath> #include <stdlib.h> using namespace std; typedef long long LL; const int inf=0x3f3f3f3f; const int mod=1e9+7; const int N=1e5+10; int a[N],ans[N]; int main() { int cas,n,x,kk=0; scanf("%d",&cas); while(cas--){ scanf("%d",&n); int cnt=0,num=0; for(int i=1;i<=n;i++){ scanf("%d",&x); if(!x) cnt++; else a[++num]=x-cnt; } if(!num) { printf("Case #%d: %d\n",++kk,cnt); continue; } int len=1; ans[1]=a[1]; for(int i=2;i<=num;i++){ if(a[i]>ans[len]) ans[++len]=a[i]; else { int pos=lower_bound(ans+1,ans+len,a[i])-ans; ans[pos]=a[i]; } } printf("Case #%d: %d\n",++kk,len+cnt); } return 0; }
0可以转化成任意整数,包括负数,显然求LIS时尽量把0都放进去必定是正确的。因此我们可以把0拿出来,对剩下的做O(nlogn)的LIS,统计结果的时候再算上0的数量。为了保证严格递增,我们可以将每个权值S[i]减去i前面0的个数,再做LIS,就能保证结果是严格递增的。
原文:http://www.cnblogs.com/smilesundream/p/5718876.html