您的位置:首页 > 其它

宴会

2015-07-24 11:52 176 查看
为率封臣们南下打击兰尼斯特家族的嚣张气焰,罗柏·史塔克决定举行一场宴会来提升封臣们的士气。史塔克家族的分封关系可以抽象成一颗树,共n个封臣。根节点为史塔克家。除史塔克家外的所有封臣均有且仅有一个直属的上级。由于经费有限,罗柏·史塔克只能邀请一部分封臣来参加宴会。经费上限用w来描述。另外,对于第i个封臣,在宴会中满足他的需要需要Ci元,所产生的士气为ei。还有一个重要的限制,就是任何封臣不希望和他的任何上级一起进行宴会,这会让他们感到拘谨。一个封臣的上级包含他的直属上级及所有间接的上级,即在这个“分封树”上从该封臣走到根的路径上所有的节点(包括根)。
现在,罗柏·史塔克希望在预算之内,所有人产生的士气最大。请你完成他的任务。

输入

单组测试数据。第一行为n(1<=n<=1200)和w(1<=w<=1000),第二行为封臣2到n的直属上级fi(即父节点),第三行为1到n的ci,第四行为1到n的ei。(1<=ci,ei<=1000) 数字间用一个空格隔开。

输入保证封臣编号按照分封树的层次关系进行,即fi一定小于i。

输出

输出一个数,代表最大的士气值。

样例输入

10 100
1 2 2 1 4 3 5 6 1
12 53 127 32 164 22 199 10 19 17
-1 0 3 5 7 -2 9 6 8 13

样例输出

27

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
#define max(a,b)  a>b?a:b
int dp[1210][1010][2];
int ci[1210],ei[1210];
vector<int>g[1210];
int n,w;
void dfs(int t)
{
if(ci[t]<w)
for(int i=ci[t];i<=w;i++)
dp[t][i][1]=ei[t];
for(int i=0;i<g[t].size();i++)
{
dfs(g[t][i]);
for(int k=w;k>=0;k--)
for(int j=1;j<=k;j++)
{
int temp=dp[t][k-j][0]+(max(dp[g[t][i]][j][1],dp[g[t][i]][j][0]));//max()外面不加括号会出错!什么鬼
dp[t][k][0]=max(dp[t][k][0],temp);
}
}
}
int main()
{
int t;
cin>>n>>w;
for(int i=2;i<=n;i++)
{
cin>>t;
g[t].push_back(i);
}
for(int i=1;i<=n;i++)
{
cin>>ci[i];
}
for(int i=1;i<=n;i++)
{
cin>>ei[i];
}
memset(dp,0,sizeof(dp));
dfs(1);
cout<<(max(dp[1][w][1],dp[1][w][0]))<<endl;
return 0;
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: