hdu5773The All-purpose Zero
阿新 • • 發佈:2019-01-27
題意:給一個n個元素的陣列,其中0可以變成任意整數,求最長上升子序列。
分析:比賽的時候一直想dp狀態,卻一直都想不到,其實和另外一題挺像的:要求改變最少個數,使得整個陣列嚴格遞增。其實就是將自身和序列要求的結合在一起。比如說這一題,0能變成任意整數,那麼0肯定是最厲害的,所有0都要在最長上升子序列裡是能夠達到的,那麼我們只需要將0對其他元素的影響減去即可(a[i]減去i之前的0的個數),然後在做普通的最長上升子序列即可。
程式碼:
#include<map> #include<set> #include<cmath> #include<queue> #include<bitset> #include<math.h> #include<vector> #include<string> #include<stdio.h> #include<cstring> #include<iostream> #include<algorithm> #pragma comment(linker, "/STACK:102400000,102400000") using namespace std; const int N=100010; const int mod=100000000; const int MOD1=1000000007; const int MOD2=1000000009; const double EPS=0.00000001; typedef long long ll; const ll MOD=1000000007; const int MAX=2000000010; const ll INF=1ll<<55; const double pi=acos(-1.0); typedef double db; typedef unsigned long long ull; int d[N]; int main() { int a,i,k,g,n,t,ca,l,r,mid; scanf("%d", &t); for (ca=1;ca<=t;ca++) { scanf("%d", &n); k=1;g=0;d[1]=-MAX; for (i=1;i<=n;i++) { scanf("%d", &a); if (a==0) g++; else { a-=g; if (a>d[k]) d[++k]=a; else { l=1;r=k;mid=(l+r)>>1; while (l+1<r) if (d[mid]<a) { l=mid;mid=(l+r)>>1; } else { r=mid;mid=(l+r)>>1; } d[r]=a; } } } printf("Case #%d: %d\n", ca, k+g-1); } return 0; }