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;
    }
    
  • 相关阅读:
    增值业务
    话题:jQuery 关于文件上传表单处理的一个非常怪异的问题
    net use 的使用
    c#开发snmp应用
    PowerDesigner15使用时的十五个问题
    一段JS代码,让你的WordPress支持简繁转换(转)
    聚集索引查询优化
    NHibernate 2.1.2相关地址
    Oracle expdp/impdp导出导入命令及数据库备份(转)
    大型ORACLE数据库优化设计方案
  • 原文地址:https://www.cnblogs.com/nanke/p/2269528.html
Copyright © 2011-2022 走看看