4999/4499 元,華碩無畏 15 推出英特爾酷睿 i7-1260P、AMD 銳龍 R5-4600H 版本
阿新 • • 發佈:2022-05-07
題意:
給定一棵樹的關係,每個節點都有對應的體積和價值,限制規則是選擇一個節點是必須選擇它的父節點,給定總體積\(m\),問能獲得的最大的價值和是多少?
- 看到是樹型結構我們可以思考樹形DP解決問題
- 考慮以\(i\)節點為根的子樹,有這樣一個事實,想選擇它的子節點那它一定會被選擇,如果不選的話就是整棵數以它為根節點的子樹都沒得選了
- 所以我們狀態設計為\(dp_{i,j}\)表示選擇以\(i\)為根的子樹總體積為\(j\)的情況下能獲得的最大價值和
- 至此\(dfs\)一遍統計答案即可
#include <bits/stdc++.h> using namespace std; int n,m,root,fa[110],v[110],w[110],dp[110][110]; //dp[i][j]表示選擇以i節點為根的子樹 總體積不超過j的方案數 可知的是i節點一定要選 //因為選子節點一定要選父節點 不選那子節點選不了 相當於一棵樹啥也不選 int head[110],tot,nxt[110],to[110]; void add(int u,int v) { to[++tot] = v,nxt[tot] = head[u],head[u] = tot; } void dfs(int u) { for(int i = v[u];i <= m;i ++) {//因為節點u一定要選 所以先初始化一下 dp[u][i] = w[u]; } for(int i = head[u];i;i = nxt[i]) { int son = to[i]; dfs(son); for(int j = m;j >= v[u];j --) { for(int k = 0;k <= j - v[u];k ++) {//列舉分給子節點的體積 dp[u][j] = max(dp[u][j],dp[u][j - k] + dp[son][k]); } } } } int main() { cin >> n >> m; for(int i = 1;i <= n;i ++) { cin >> v[i] >> w[i] >> fa[i]; if(fa[i] == -1) { root = i; continue; } add(fa[i],i); } dfs(root); cout << dp[root][m] << '\n'; return 0; }