• 宴会


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

      

  • 相关阅读:
    理解volatile与synchronized
    实现任意两个数的互换
    增删改查+部分前段内容
    Hibernate知识点小结汇总
    Spring知识点小结(一)
    JDBC相关
    Redis工具之Jedis
    Hibernate知识点小结(四)--JPA
    Hibernate知识点小结(三)-->一对多与多对多配置
    Hibernate知识点小结(二)
  • 原文地址:https://www.cnblogs.com/duanyuanzhi/p/4673046.html
Copyright © 2020-2023  润新知