zoukankan      html  css  js  c++  java
  • hdu1520 Anniversary party(树形dp)

    题意:在一棵树上选出一些点,每个点都有一个权值,使得和最大,前提是,父节点和子节点只能选一个。

    分析:整个代码与1054基本一样的,就是状态转移方程变了 ,因为题目加了一些限制

    dp[i][0]表示以i为根节点的不选i树的最大权值和

    dp[i][1]表示以i为根节点的选i的树的最大权值和

    状态转移方程:

    dp[i][0]+=max(dp[son[i][j]][0],dp[son[i][j]][1]),(0<j<size[i])

    dp[i][1]+=dp[son[i][j]][0];(0<j<size[i]) size[i]表示i节点的儿子数

    #include<iostream>
    #include<algorithm>
    #include<vector>
    using namespace std;
    int v[6001],n,f[6001];
    vector<int> son[6001];
    int dp[6001][2];
    int dfs(int pos,int val)
    {
    	if(dp[pos][val]!=INT_MIN)
    		return dp[pos][val];
    	int sum;
    	if(val==1)
    		sum=v[pos];
    	else sum=0;
    	int size=son[pos].size();
    	for(int i=0;i<size;i++)
    	{
    		if(val==1)
    			sum+=dfs(son[pos][i],0);
    		else sum+=max(dfs(son[pos][i],0),dfs(son[pos][i],1));
    	}
    	return dp[pos][val]=sum;
    }
    int main()
    {
    	while(scanf("%d",&n)==1)
    	{
    		for(int i=1;i<=n;i++)
    		{
    			scanf("%d",&v[i]);
    			son[i].clear();
    			f[i]=i;
    			dp[i][0]=dp[i][1]=INT_MIN;
    		}
    		int a,b;
    		while(scanf("%d %d",&a,&b))
    		{
    			if(a==0 && b==0)
    				break;
    			son[b].push_back(a);
    			f[a]=b;
    		}
    		int ans;
    		for(int i=1;i<=n;i++)
    		{
    			if(f[i]==i)
    			{
    				ans=max(dfs(i,0),dfs(i,1));
    				break;
    			}
    		}
    		printf("%d\n",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    怎么强制限制div宽度
    KeyWordHelper关键字提取类(注:使用第三方组件DictSeg.dll)
    XmlToJsonxml对象转换为Json对象类
    Excel模板导出(针对复杂报表的一种解决方式)
    SQL查询xml内容
    ASP.NET中使用jQGrid
    RandomHelper随机数辅助类
    Translater语言翻译类
    Int32.Parse, Convert.ToInt32,Int32.TryParse三者的区别
    CollectionHelper网页采集辅助类
  • 原文地址:https://www.cnblogs.com/nanke/p/2269528.html
Copyright © 2011-2022 走看看