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;
}

 

 

posted @ 2018-12-24 19:23  AKCqhzdy  阅读(152)  评论(0编辑  收藏  举报