dp新优化姿势。。。
首先,当我们拔高时,一定右端点是n最优。因为如果右端点是r,相当于降低了r之后玉米的高度。显然n更优。
那么可以dp。dp[i][j]表示前i个拔高j次的LIS。dp[i][j]=max(dp[i'][j'])+1,其中h[i']+j'>=h[i],j'<=k
可以用二位树状数组来维护。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 10005 4 #define lowbit(x) (x&-x) 5 int n,k,h[N],r[N][505],H,ans; 6 int read(){ 7 int tmp=0,f=1,a=getchar(); 8 while(a<'0' || a>'9') {if(a=='-') f=-1; a=getchar();} 9 while(a>='0' && a<='9') tmp=tmp*10+a-'0',a=getchar(); 10 return tmp*f; 11 } 12 void update(int x,int y,int a){ 13 for(int i=x;i<=H+k;i+=lowbit(i)) 14 for(int j=y;j<=k+1;j+=lowbit(j)) 15 r[i][j]=max(r[i][j],a); 16 } 17 int query(int x,int y){ 18 int ret=0; 19 for(int i=x;i;i-=lowbit(i)) 20 for(int j=y;j;j-=lowbit(j)) 21 ret=max(ret,r[i][j]); 22 return ret; 23 } 24 int main(){ 25 n=read(); k=read(); 26 for(int i=1;i<=n;i++) h[i]=read(),H=max(H,h[i]); 27 for(int i=1;i<=n;i++) 28 for(int j=k;j>=0;j--){ 29 int tmp=query(h[i]+j,j+1)+1; 30 ans=max(ans,tmp); 31 update(h[i]+j,j+1,tmp); 32 } 33 printf("%d ",ans); 34 return 0; 35 }