【洛谷P1107】 [BJWC2008]雷涛的小猫
雷涛的小猫
n^2DP比较好想,
f[i][j]表示第i棵树高度为j的最大收益
直接从上到下转移即可,每次记录下max f[1~n][j]
用于下面的转移
f[i][j]=max(f[i][j-1],max(f[1~n][j-Delta]))
max(f[1~n][j-Delta])是已经求出来的,O(1)查询
枚举j和i,总复杂度为O(n^2)
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 using namespace std; 5 #define N 2010 6 inline int read(){ 7 int x=0; char c=getchar(); 8 while(c<'0'||c>'9') c=getchar(); 9 while('0'<=c&&c<='9') { x=(x<<3)+(x<<1)+c-'0'; c=getchar(); } 10 return x; 11 } 12 int n,m,k,dp[N][N],M,a[N][N],maxn[N],ans; 13 int main() 14 { 15 scanf("%d%d%d",&n,&m,&k); 16 int x,y; 17 for(int i=1;i<=n;i++){ 18 x=read(); 19 for(int j=1;j<=x;j++){ 20 y=read(); a[i][y]++; 21 } 22 } 23 for(int i=1;i<=m;i++){ 24 for(int j=1;j<=n;j++){ 25 if(i<k){ 26 dp[j][i]=dp[j][i-1]+a[j][i]; 27 maxn[i]=max(maxn[i],dp[j][i]); 28 continue; 29 } 30 dp[j][i]=max(maxn[i-k],dp[j][i-1])+a[j][i]; 31 maxn[i]=max(maxn[i],dp[j][i]); 32 } 33 } 34 printf("%d\n",maxn[m]); 35 return 0; 36 }