The more, The Better
分類:
dfs and similar
dp
trees
1.題意概述
- ACboy很喜歡玩一種戰略遊戲,在一個地圖上,有N座城堡,每座城堡都有一定的寶物,在每次遊戲中ACboy允許攻克M個城堡並獲得裏面的寶物。但由於地理位置原因,有些城堡不能直接攻克,要攻克這些城堡必須先攻克其他某一個特定的城堡。你能幫ACboy算出要獲得儘量多的寶物應該攻克哪M個城堡嗎?
- 輸入:每個測試實例首先包括2個整數,
N,M.(1≤M≤N≤200) ;在接下來的N行裏,每行包括2個整數,a,b. 在第 i 行,a 代表要攻克第 i 個城堡必須先攻克第 a 個城堡,如果 a = 0 則代表可以直接攻克第 i 個城堡。b 代表第 i 個城堡的寶物數量,b≥0 。當N = 0, M = 0輸入結束。
2.解題思路
我們定義
dp[i][j] 爲當前i節點及其子樹下最多選擇j個城市的最大值,那麼對於某個節點p :- 判斷
p 當前有沒有孩子,如果有則繼續dfs下去(這就是樹形dp的過程),否則進入操作2。 - 將
p 的狀態更新到父親p‘ 上:dp[p‘][i]=max(dp[p‘][j]+dp[p][k]) ,其中j+k=i,j>0,k>0,2≤i≤bmax
那麼答案就是
dp[0][bmax] !- 判斷
3.AC代碼
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define maxn 10010
#define lson root << 1
#define rson root << 1 | 1
#define lent (t[root].r - t[root].l + 1)
#define lenl (t[lson].r - t[lson].l + 1)
#define lenr (t[rson].r - t[rson].l + 1)
#define N 202
#define eps 1e-6
#define pi acos(-1.0)
#define e exp(1.0)
using namespace std;
const int mod = 1e9 + 7;
typedef long long ll;
typedef unsigned long long ull;
int head[N], v[N] , dp[N][N], cnt; // 0上最長,1下次長,2下最長
struct node
{
int to, next;
} E[N << 1];
void init()
{
memset(head, -1, sizeof head);
memset(dp, 0, sizeof(dp));
cnt = 0;
}
void addedge(int u, int v)
{
E[cnt].to = v;
E[cnt].next = head[u];
head[u] = cnt++;
}
void dfs(int u, int res)
{
dp[u][1] = v[u];
if (res == 1)
return;
for (int i = head[u]; i != -1; i = E[i].next)
{
int v = E[i].to;
dfs(v, res - 1);
for (int j = res; j > 1; j--)
for (int k = 1; k < j; k++)
dp[u][j] = max(dp[u][j], dp[u][j - k] + dp[v][k]);
}
}
int main()
{
int n, m;
while (~scanf("%d%d", &n, &m), n + m)
{
init();
for (int i = 1; i <= n; i++)
{
int a, b;
scanf("%d%d", &a, &b);
addedge(a, i);
v[i] = b;
}
dfs(0, m + 1);
printf("%d\n", dp[0][m + 1]);
}
return 0;
}