bzoj3594: [Scoi2014]方伯伯的玉米田

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 }
原文地址:https://www.cnblogs.com/enigma-aw/p/5973364.html