【洛谷】P1352 没有上司的舞会

【洛谷】P1352 没有上司的舞会


0.总结

Get to the points first. The article comes from LawsonAbs!

树上dp题

  • (1)以节点从深到前(子树从小到大)的顺序作为dp的 “阶段”
  • (2)dp的状态表示中,第一维通常是节点编号(代表以该节点为根的子树)
  • (3)大多数的时候,以递归的形式实现树性动态规划。对于每个节点x,递归的求出其子节点,然后回溯的时候根据转移方程求出根节点x的状态值。

1.题目

2.思路

没什么难点,只要会图的遍历(dfs)+简单dp知识 即可。

  • dp[i][0]表示以i为根的树在i不参加的情况下达到的最大快乐值;dp[i][1]表示以i为根的树在i参加的情况下达到的最大快乐值;
  • hap[i]表示节点i参会的快乐值
  • 状态转移方程很简单。因为笔者太蒟蒻了(不会用Latex公式),所以就不给出来了。

3.代码

#include<iostream>
#include<vector>
using namespace std;
const int N = 6005;
int dp[N][2], hap[N],isR[N];//快乐值 ;判断是否是根节点 
int n,root;//多少个节点; 根是什么 
vector<int> ver[N];//每个节点的子节点序号 

void dfs(int cur){
	for(int i = 0;i<ver[cur].size();i++){
		int y = ver[cur][i];//子树的序号
		dfs(y);		
		dp[cur][0] +=  max(dp[y][0],dp[y][1]);//cur节点不参加 
		dp[cur][1] += dp[y][0]; 
	} 
	dp[cur][1]+=hap[cur];//cur节点要参加,自己的快乐指数也要加上 
}

int main(){	
	cin >> n;
	for(int i = 1;i<= n;i++){
		cin >> hap[i];
	} 
	int a,b;
	for(int i = 0;i<n-1;i++){
		cin  >> a >> b;
		ver[b].push_back(a);//b->a 
		isR[a] = 1;
	}
	//先找出根序号 
	for(int i = 1;i<=n;i++){
		if(!isR[i])//说明节点i是根节点 
		{
			root = i; dfs(i);
		}
	}
	//cout << root<<"\n";
	cout << max(dp[root][0],dp[root][1])<<"\n";
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

说文科技

看书人不妨赏个酒钱?

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值