题意
简单来说就是有一只猫,去吃柿子。
大家还是自己去看题目吧qwq
分析
设dp[i][j]表示第i棵树上第j层可以获得的最大的收益。
转移也很显然:
dp[i][j] = max(dp[i][j+1],dp[k][j+d])+num[i][j]
但是这个东西的复杂度是(n^3)的
但是,显然我们只需要dp[k][j+d]的最大值去更新答案。
我们显然可以在更新的时候把上面的层j+d的答案给求出来。
于是复杂度就变成(n^2)的了。
现在设dp[i][0]表示第i层的最大值,任何树都可以。
dp[j][1]表示当前枚举的高度在第j层的最大值。
于是这题就做完了。
#include <bits/stdc++.h>
#define sc(n) scanf("%d",&n)
#define pt(n) printf("%d\n",n)
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define vi vector<int>
#define vl vector<long long>
#define pb push_back
using namespace std;
typedef long long ll;
const int maxn = 2010;
int dp[maxn][2];
int t[maxn][maxn];
int num[maxn];
int n,h,d;
int main()
{
scanf("%d%d%d",&n,&h,&d);
for(int i=1;i<=n;i++)
{
sc(num[i]);
for(int j=1;j<=num[i];j++)
{
int tmp;
sc(tmp);
t[i][tmp]++;
}
}
for(int i=h;i>=1;i--)
{
int tmp = (i+d<=h)?dp[i+d][0]:0;
for(int j=1;j<=n;j++)
{
dp[j][1] = max(dp[j][1],tmp)+t[j][i];
dp[i][0] = max(dp[j][1],dp[i][0]);
}
}
printf("%d\n",dp[1][0]);
return 0;
}