The more, The Better
题意:现有N座城堡,每座城堡有bi的宝藏,现在最多攻破M座城堡,且攻城要按顺序,要共攻破第i座城堡必须先攻破第j座城堡;
首先是个背包问题,其次不难看出,每座城堡之间的联系是片森林,所以想到树形dp
令dp[i][j]表示第i个节点处,攻破的城堡有j座(包括其本身和子节点);
#include <bits/stdc++.h>
using namespace std;
int N, M, dp[210][210], val[210];
vector<int> vec[210];
void dfs(int root){
for(int i=1; i<=M; i++)
dp[root][i]=val[root];
for(int i=0; i<vec[root].size(); i++){
int son=vec[root][i];
dfs(son);
for(int j=M; j>1; j--){//j>1是因为root节点本身一定要攻破;
for(int k=0; k<j; k++){//k表示在子节点攻破的城堡;
dp[root][j]=max(dp[root][j], dp[son][k]+dp[root][j-k]);
}
}
}
}
int main(){
while(scanf("%d%d", &N, &M), N||M){
M++;
for(int i=0; i<=N; i++) vec[i].clear();
for(int i=1; i<=N; i++){
int a;
scanf("%d%d", &a, &val[i]);
vec[a].push_back(i);
}
val[0]=0;
memset(dp, 0, sizeof(dp));
dfs(0);
printf("%d\n", dp[0][M]);
}
return 0;
}