标签:
给定n个地点,每个地点藏有cost[i]的宝物,取得某些宝物有时需要先取其他宝物,现在让我们选m个地点问最多可以选多少宝物?
还是挺裸的树形背包dp吧,不难,关键还是中间dp的部分。可以做模板了->_->
注意点:多组数据的话如果第一组对了然后其他都错了,那么很有可能是初始化的时候漏了。这次找可很久才知道差了e[0].clear().平时的习惯都是从1开始。
-----------------------------------------------------------------------------------------
#include<cstdio>
#include<cstring>
#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;
#define rep(i,n) for(int i=1;i<=n;i++)
#define clr(x,c) memset(x,c,sizeof(x))
int read(){
int x=0,f=1;char c=getchar();
while(!isdigit(c)){
if(c==‘-‘) f=-1;
c=getchar();
}
while(isdigit(c)){
x=x*10+c-‘0‘;
c=getchar();
}
return x*f;
}
int sum[205],f[205][205],w[205],n,m;
vector<int>e[205];
void dfs(int x){
sum[x]=1;
for(int i=0;i<e[x].size();i++){
dfs(e[x][i]);
sum[x]+=sum[e[x][i]];
}
for(int i=0;i<e[x].size();i++){
int to=e[x][i];
for(int j=min(sum[x],m);j>=1;j--)
for(int k=1;k<=j;k++)
f[x][j]=max(f[x][j],f[x][j-k]+f[to][k]);
}
if(x) for(int i=m;i>=1;i--) f[x][i]=f[x][i-1]+w[x];
return ;
}
int main(){
while(scanf("%d%d",&n,&m)==2&&n&&m){
clr(sum,0);clr(f,0);
e[0].clear();
rep(i,n) e[i].clear();
rep(i,n){
int tmp=read();w[i]=read();
e[tmp].push_back(i);
}
dfs(0);
printf("%d\n",f[0][m]);
}
return 0;
}
-----------------------------------------------------------------------------------------
Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 6647 Accepted Submission(s): 3913
标签:
原文地址:http://www.cnblogs.com/fighting-to-the-end/p/5058151.html