In the first case,you can change the second 0 to 3.So the longest increasing subsequence is 0 1 2 3 5.
给你一个数列 其中0可以变为任意一个数 问你最大递增子序列长度是多少
0可以变为任意数 把所有的0加入肯定是最优的 我们可以先找出除了0之外的最大递增子序列 再加上0的个数
要注意 1 2 0 3 这种情况会出现错误 我们需要让每个数减去在它之前的0的个数 这样我们就能得到严格递增的序列
前面的例子就变为1 2 0 2
再举个例子 12 0 3 5 0 0 0 6 9 变化之后为1 2 0 2 4 0 0 0 2 5 最大递增子序列为 1 2 4 5 最大长度为8
下面有用到lower_bound() 点击查看它的用法
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int a[100001]; int b[100001]; int d[100001]; int vis[100001]; int main() { int t,ans=0;; scanf("%d",&t); while(t--) { ans++; int n,m; scanf("%d",&n); int sum=0; int cnt=0; for(int i=1;i<=n;i++) { scanf("%d",&m); if(m==0) { sum++; } else { a[++cnt]=m-sum;//存入一个新的数组 } } if(cnt==0) { printf("Case #%d: %d\n",ans,sum); continue; } int len=1; d[1]=a[1]; for(int i=2;i<=cnt;i++) { if(a[i]>d[len]) { len++; d[len]=a[i]; } else { int pos=lower_bound(d+1,d+len,a[i])-d;//这里和下面的二分查找作用是一样的 用起来更方便一些 d[pos]=a[i]; /* int l=1; int r=len; int mid; int cut; while(l<=r) { mid =(l+r)/2; if(a[i]<d[mid]) { cut=mid; r=mid-1; } else { l=mid+1; } } d[cut]=a[i]; */ } } printf("Case #%d: %d\n",ans,len+sum); } return 0; }