HDU 5773 The All-purpose Zero
给你一个序列,0可以变成任意数字,文最长上升子序列长度。
首先最长的肯定是0都用。
因为中间无论多少个0都不会让情况更糟糕。
然后,0单独拿出来,最后统计的时候加上就行。
最后,每个数的实际值要减去它之前的0的个数,因为要让每一个0都物尽其用,能在这个数之前塞得下。也就是说这个数会变得没有那么值钱,如果减了之后依然能排最后,那只能说明这个数本来和之前的空间就已经够放下那么多0了。
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <queue> #include <vector> using namespace std; int a[100100]; int dp[100100]; int main() { int T,kacs=0; scanf ("%d",&T); while (T--) { int n; scanf ("%d",&n); for (int i=1;i<=n;i++) scanf ("%d",&a[i]); int maxn=0,num=0,ans=1; for (int i=1;i<=n;i++) { if (maxn==0) { if (a[i]==0) num++; else dp[++maxn]=a[i]-num; ans=max(ans,num+maxn); } else { if (a[i]==0) num++; else { a[i]-=num; if (a[i]>dp[maxn]) dp[++maxn]=a[i]; else { int pos=lower_bound(dp+1,dp+maxn,a[i])-dp; dp[pos]=a[i]; } } ans=max(ans,num+maxn); } } printf ("Case #%d: %d\n",++kacs,ans); } return 0; }