Description
ACboy很喜欢玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中ACboy允许攻克M个城堡并获得里面的宝物。但由于地理位置原因,有些城堡不能直接攻克,要攻克这些城堡必须先攻克其他某一个特定的城堡。你能帮ACboy算出要获得尽量多的宝物应该攻克哪M个城堡吗?
Output
对于每个测试实例,输出一个整数,代表ACboy攻克M个城堡所获得的最多宝物的数量。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
int N,M,v[223];
vector<int>son[223];
int dp[223][223];
void dfs(int n,int left){
int i,j,k,len=son[n].size();
dp[n][1]=v[n];
for(i=0;i<len;i++){
if(left>1) dfs(son[n][i],left-1);
for(j=left;j>=1;j--)
for(k=1;k<=j;k++)
if(dp[n][j+1]< dp[n][j+1-k] +dp[son[n][i]][k]) dp[n][j+1]=dp[n][j+1-k]+dp[son[n][i]][k];
// 其他儿子的总值 第i个儿子取k个
}
}
int main()
{
int i,j,k;
while(scanf("%d%d",&N,&M),N||M)
{
//
memset(v,0,sizeof(v));
memset(dp,0,sizeof(dp));
for(i=0;i<=N;i++) son[i].clear();
//
for(i=1;i<=N;i++){
scanf("%d%d",&j,&v[i]);
son[j].push_back(i);
}
dfs(0,M+1);
printf("%d\n",dp[0][M+1]);
}
return 0;
}
#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
#define maxn 205
using namespace std;
int n,m;
int f[maxn][maxn],w[maxn];
vector <int>g[maxn];
void before(){
memset(f,0,sizeof(f));
memset(w,0,sizeof(w));
for(int i=0;i<=n;i++)g[i].clear();
}
void dfs(int u){
for(int l=0;l<g[u].size();l++){
int v=g[u][l];
if(u!=0){
dfs(v);
for(int i=m;i>=1;i--)
for(int j=0;j<i;j++){
f[u][i]=max(f[u][i],f[v][j]+f[u][i-j]);
}
}
else{
dfs(v);
for(int i=m;i>=1;i--)
for(int j=1;j<=i;j++){
f[u][i]=max(f[u][i],f[v][j]+f[u][i-j]);
}
}
}
}
int main(){
while(scanf("%d%d",&n,&m)&&n+m){
before();
for(int i=1;i<=n;i++){
int fa;
scanf("%d%d",&fa,&w[i]);
f[i][1]=w[i];
g[fa].push_back(i);
}
dfs(0);
printf("%d\n",f[0][m]);
}
return 0;
}
多叉树转二叉写法:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#define clr(a,b) memset(a,b,sizeof(a))
using namespace std;
const int maxn = 210;
const int maxm = 210;
bool vis[maxn][maxm];
int n,m,last[maxn],p[maxn],w[maxn],f[maxn][maxm],l[maxn],r[maxn];
int dp(int x,int cnt)
{
if(vis[x][cnt])return f[x][cnt];
vis[x][cnt] = true;
if(x == 0)return f[x][cnt] = 0;
f[x][cnt] = dp(r[x],cnt);
for(int k = 0;k < cnt;++k)
f[x][cnt] = max(f[x][cnt],dp(l[x],k)+dp(r[x],cnt-k-1)+w[x]);
return f[x][cnt];
}
int main()
{
while(scanf("%d%d",&n,&m) && n)
{
clr(last,0);clr(p,0);clr(l,0);clr(r,0);
clr(vis,0);clr(w,0);
for(int i = 1;i <= n;++i)
{
scanf("%d%d",&p[i],&w[i]);
if(!last[p[i]])l[p[i]] = i;
else r[last[p[i]]] = i;
last[p[i]] = i;
}
clr(f,-1);
printf("%d\n",dp(l[0],m));
}
return 0;
}