题意
https://www.luogu.com.cn/problem/P1270
分析
经典的树上背包,令\(dp[x][t]\)表示在\(x\)点剩余\(t\)秒的最多画数
在\(x\)结点考虑分给左右结点的时间,故枚举分给左儿子的时间\(i\),那么分给右儿子的时间就是\(t-i-cost[x]\):
\[dp[x][t]=max(dp[x][t],dp[x<<1][i]+dp[x<<1|1][t-i-cost[x]]) \]答案即是\(dp[1][T]\)
Code
#include<iostream>
#include<cstdio>
#include<vector>
const int maxn = 200 + 10;
int T;
int cost[maxn], val[maxn];
int dp[maxn][2000 + 10];
void read(int x) {
int a, b;
scanf("%d%d", &a, &b);
cost[x] = 2 * a;
val[x] = b;
if (val[x]) return;
read(x << 1);
read(x << 1 | 1);
}
void dfs(int x) {
if (val[x]) {
for (int i = 0; i <= val[x]; i++) {
if (i * 5 + cost[x] > T)break;
dp[x][i * 5 + cost[x]] = i;
}
return;
}
dfs(x << 1);
dfs(x << 1 | 1);
for (int i = cost[x]; i <= T; i++)
for (int j = 0; j <= i - cost[x]; j++)
dp[x][i] = std::max(dp[x][i], dp[x << 1][j] + dp[x << 1 | 1][i - j - cost[x]]);
}
int main() {
scanf("%d", &T);
T--;
read(1);
dfs(1);
printf("%d", dp[1][T]);
return 0;
}
标签:洛谷,val,int,cost,maxn,P1270,dp
From: https://www.cnblogs.com/MrWangnacl/p/16908627.html