宴会

        为率封臣们南下打击兰尼斯特家族的嚣张气焰,罗柏·史塔克决定举行一场宴会来提升封臣们的士气。史塔克家族的分封关系可以抽象成一颗树,共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;
} 

  

posted @ 2015-07-24 11:52  尽善尽美#  Views(157)  Comments(0Edit  收藏  举报