IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> ? 树形dp ? -> 正文阅读

[数据结构与算法]? 树形dp ?

没有上司的舞会

P1352 没有上司的舞会 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

此题画出来是一种这样的结构(有一种“前向星存图”的方法,但这题没必要用)

同样可以采取dp的思考方式

dp[n][2] 数组代表每个人做出决策之后的快乐值,0是不去,1是去

1.初始化

dp[x][0]=0;

dp[x][1]=r[x];

2.状态转移方程

如果x是当前职工,y是他的下属,那么:

dp[x][0]+=max(dp[y][0],dp[y][1]); //上司没去,下属要么去,要么不去,那就取一个max

dp[x][1]+=dp[y][0];? ? ? ? //上司去了下属不去

那么,我们如何获取所有下属的每一种情况呢——树形结构——遍历+递归!

void dfs(int x){
	//树形dp常常要用递归,自底向上
	dp[x][0]=0;	//不参加,带来的快乐值贡献为0
	dp[x][1]=r[x]; //参加
	for(int i=0;i<son[x].size();i++){
		//遍历ta的所有下属
		int y=son[x][i];	//y是当前遍历到的下属的编号
		dfs(y);
		dp[x][0]+=max(dp[y][0],dp[y][1]);
		dp[x][1]+=dp[y][0]; 
	} 
} 

在遍历中就更新了dp数组~~~

那么,把谁作为参数传进去呢?

显然应该传“树根”——树根就是没有上司的那一个人(而且题目中说了这是树,不会有图那种情况)

所以再额外设定一个v数组,来记录每一个员工有没有上司

当我们记忆化搜索了所有的情况,dp数组也都有了值,现在就要获取答案了

很简单,树根收集了所有子树的情况:

?? ?cout<<max(dp[root][0],dp[root][1])<<endl;

至此完成

完整代码:

#include<iostream>
#include<vector>
using namespace std;

#define MAXN 6005
int r[MAXN];		//快乐指数 
int v[MAXN];
vector<int> son[MAXN];	//每个人都存一个自己的下属数组
int dp[MAXN][2]; //dp[i]代表第i个人,0不去,1去

void dfs(int x){
	//树形dp常常要用递归,自底向上
	dp[x][0]=0;	//不参加,带来的快乐值贡献为0
	dp[x][1]=r[x]; //参加
	for(int i=0;i<son[x].size();i++){
		//遍历ta的所有下属
		int y=son[x][i];	//y是当前遍历到的下属的编号
		dfs(y);
		dp[x][0]+=max(dp[y][0],dp[y][1]);
		dp[x][1]+=dp[y][0]; 
	} 
} 

int main(){
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
		cin>>r[i];
	for(int i=1;i<n;i++){
		int x,y;
		cin>>x>>y;
		son[y].push_back(x);
		v[x]=1;	//代表ta有上司 
	}
	int root;
	for(int i=1;i<=n;i++){
		if(!v[i]){
			root=i;
			break;	//找到没有上司的那个人 
		}
	} 
	dfs(root);
	cout<<max(dp[root][0],dp[root][1])<<endl;
    return 0;
}

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-05-04 07:30:14  更:2022-05-04 07:30:18 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 5:26:40-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码