bzoj1270 [BeijingWc2008]雷涛的小猫(dp)

来源:互联网 发布:mac word 改写快捷键 编辑:程序博客网 时间:2024/05/01 22:38

比较水的dp,dp[i][j]表示高度为i,在第j棵树上时能获得的最大值。状态转移方程:dp[i][j]=max(dp[i+1][j],dp[i+del][?])+f[j][i]。为了让决策变成O(1)的,我们带着个数组f。f[i]表示在高度i时能获得的最大值。这样决策就变成O(1)得了。转移是O(1)的,状态是O(nh)的,总的时间复杂度是O(nh)的。

#include <cstdio>#include <cstring>#define N 2010int n,h,del,a[N][N],f[N],dp[N][N];//f[i],高度为i时能获得的最大值 inline int read(){    int x=0,f=1;char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();    return x*f;}inline int max(int x,int y){return x>y?x:y;}int main(){//  freopen("a.in","r",stdin);    n=read();h=read();del=read();    for(int i=1;i<=n;++i){        int x=read(),y;        while(x--) y=read(),a[i][y]++;    }    for(int i=h;i>=1;--i){        for(int j=1;j<=n;++j){            if(i+del<=h) dp[i][j]=max(dp[i+1][j],f[i+del]);            else if(i<h) dp[i][j]=dp[i+1][j];else dp[i][j]=0;            dp[i][j]+=a[j][i];if(dp[i][j]>f[i]) f[i]=dp[i][j];         }    }    printf("%d\n",f[1]);    return 0;}