题目链接
https://www.luogu.com.cn/problem/P1270
思路
我们定义 d p [ i ] [ j ] dp[i][j] dp[i][j]表示当前节点为 i i i,且背包容量为 j j j秒时所能偷走的画的最大值。
在进行状态转移的时候,如果当前节点是叶子节点,就判断能取多少。如果是分叉路口,就枚举分别分配给左右子树的时间来进行转移。
代码
cpp
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int>pii;
const int N = 6e3 + 5, M = 1e6 + 5;
const int mod = 998244353;
int n, cnt;
int dp[N][N];//当前节点为i用掉j秒能偷到的画的数量的最大值
void dfs()
{
int root = ++cnt, time, num;
cin >> time >> num;
time <<= 1;
if (num)
{
for (int i = time; i <= n; i++)
{
dp[root][i] = min(num, (i - time) / 5);
}
}
else
{
int left = cnt + 1;
dfs();
int right = cnt + 1;
dfs();
for (int i = time; i <= n; i++)
{
for (int lr = 0; lr <= i - time; lr++)
{
dp[root][i] = max(dp[root][i], dp[left][lr] + dp[right][i - time - lr]);
}
}
}
}
void solve()
{
cin >> n;
n--;
dfs();
cout << dp[1][n] << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int test = 1;
// cin >> test;
for (int i = 1; i <= test; i++)
{
solve();
}
return 0;
}