HDU1520 Anniversary party

本文深入探讨了树形DP的概念及其在解决具有层次结构数据问题时的优势。通过实例解析,展示如何通过设置状态转移方程来求解最大化问题,同时提供了一段AC_CODE示例代码,帮助读者理解实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这里有一个对树形dp简单的介绍:http://wenku.baidu.com/view/03d35d1c59eef8c75fbfb3b4.html
暂时的理解是如果题目中的数据具有层次结构(如树)等,且要求最优解,则可以考虑使用树形dp。
这道题可以简单的描述为有一些数据之间有父子关系,现在需要选择一些数据出来,使数据总的和最大,但要求数据两两之间不能有直接的父子关系。若设节点i为某一个根,则可以设dp[i][0]表示不包括i的子树的最大和,dp[i][1]表示包括节点i的子树的最大和。则最终所求的结果为:
ans=max{dp[i][0],dp[i][1]}

dp[i][0]=sum(max{dp[j][0],dp[j][1]}) //如果不包括i,则其子树的最大和是不包括其孩子

        //或者包括其孩子两种可能下的最大和

dp[i][1]=sum(dp[j][0]) //如果包括i,则只能是不包括其孩子的最大和

AC_CODE:

#include <stdio.h>
#include <memory.h>

#define N 6005

struct node
{
	int v;
	node *next;
};
node *vertices[N],edges[N];
int rating[N];
int dp[N][2];
int ind[N];
int cnt;

void dfs(int u)
{
	if(!vertices[u])
	{
		dp[u][0]=0;
		dp[u][1]=rating[u];
		return;
	}
	int v;
	dp[u][1]+=rating[u];
	for(node *n=vertices[u];n;n=n->next)
	{
		v=n->v;
		dfs(v);
		dp[u][0]+=(dp[v][0]<dp[v][1])?dp[v][1]:dp[v][0];
		dp[u][1]+=dp[v][0];
	}
}
int main()
{
	int n,L,K,root;
	while(scanf("%d",&n)!=EOF)
	{
		cnt=0;
		memset(vertices,0,sizeof(vertices));
		memset(dp,0,sizeof(dp));
		memset(ind,0,sizeof(ind));
		for(int i=1;i<=n;i++)
			scanf("%d",&rating[i]);
		while(scanf("%d%d",&L,&K)&&(L||K))
		{
			edges[cnt].v=L;
			edges[cnt].next=vertices[K];
			vertices[K]=&edges[cnt++];
			ind[L]++;
		}
		for(root=1;root<=n;root++)
		{
			if(!ind[root])
			{
				dfs(root);
				break;
			}
		}
		printf("%d\n",(dp[root][0]>dp[root][1])?dp[root][0]:dp[root][1]);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值