bzoj3594: [Scoi2014]方伯伯的玉米田
明显是要上DP的。虽然我只能想出5个for起步。。。然后云里雾里瞎搞搞不知道乱搞成什么样
反正枚举到那个玉米那一维可以省掉,然后就一个操作数一个高度,看看范围可以用二维树状数组优化下
就是令f[i][j]表示到了当前操作了i次最高位为j最多保留的玉米,这个可以直接扔到树状数组里面
弄一个辅助数组更新一下就可以了。注意因为树状数组没法到0所以全部往后推了一位
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; int n,K,M,s[510][6100]; int lowbit(int x){return x&-x;} void change(int x,int y,int k) { int ty=y; while(x<=K) { y=ty; while(y<=M) { s[x][y]=max(s[x][y],k); y+=lowbit(y); } x+=lowbit(x); } } int getmax(int x,int y) { int ret=0,ty=y; while(x>0) { y=ty; while(y>0) { ret=max(ret,s[x][y]); y-=lowbit(y); } x-=lowbit(x); } return ret; } int a[11000],f[510]; int main() { freopen("a.in","r",stdin); freopen("a.out","w",stdout); M=0; scanf("%d%d",&n,&K); K++; for(int i=1;i<=n;i++) scanf("%d",&a[i]), M=max(M,a[i]); M+=K; int ans=0; for(int i=1;i<=n;i++) { for(int j=1;j<=K;j++) { f[j]=getmax(j,a[i]+j)+1; ans=max(ans,f[j]); } for(int j=1;j<=K;j++) change(j,a[i]+j,f[j]); } printf("%d\n",ans); return 0; }
pain and happy in the cruel world.