20251116 树状DP总结

引子

树形DP是一种基于树结构的动态规划算法,利用树的递归特性进行状态转移。根据兄弟节点间的约束关系,可分为两种类型:

  1. 无相互约束型:兄弟节点的决策互不影响
  2. 有相互约束型:兄弟节点的决策相互制约

P3155 [CQOI2009] 叶子的染色

1.状态
dp[i][0/1]表示以i为根的子树且点i染色为0或1,且子树内叶子合法的最少染色数。

2.答案
min(dp[m][0],dp[m][1])

3.转移

考虑cur->nxt父子关系

cpp 复制代码
dfs(nxt,cur);
dp[cur][0]+=min(dp[nxt][0]-1,dp[nxt][1]);

4.code实现

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int m,n,c[5025],dp[10005][2];
vector<int> E[10005];
void dfs(int x,int fa){
	dp[x][0]=dp[x][1]=1;
	if(x<=n){
		dp[x][1-c[x]]=1e9;
	}
	for(int i=0;i<E[x].size();i++){
		int v=E[x][i];
		if(v==fa)continue;
		dfs(v,x);
		dp[x][0]+=min(dp[v][0]-1,dp[v][1]);
		dp[x][1]+=min(dp[v][1]-1,dp[v][0]);
	}
}
int main(){
	cin>>m>>n;
	for(int i=1;i<=n;i++){
		cin>>c[i];
	}
	for(int i=1;i<m;i++){
		int u,v;
		cin>>u>>v;
		E[u].push_back(v);
		E[v].push_back(u);
	}
	dfs(m,0);
	cout<<min(dp[m][0],dp[m][1]);
	return 0;
}
相关推荐
吃好睡好便好5 小时前
用while循环语句求和
开发语言·学习·算法·matlab·信息可视化
王璐WL5 小时前
【C语言入门级教学】函数的概念2
c语言·数据结构·算法
不知名的忻6 小时前
B 树与 B+ 树:面试完全指南
b树·算法·面试·b+树
运筹vivo@7 小时前
2657. 找到两个数组的前缀公共数组 | 难度:中等
算法·leetcode·职场和发展·哈希表
索木木7 小时前
NCCL SHARP 和 TREE算法
java·服务器·算法
心中有国也有家8 小时前
hccl 架构拆解:昇腾集合通信库到底在做什么?
人工智能·经验分享·笔记·分布式·算法·架构
小O的算法实验室9 小时前
2026年MCS,Q-learning增强MOPSO与改进DWA融合算法+复杂三维地形下特定移动机器人动态路径规划
算法
Peter·Pan爱编程9 小时前
10. new_delete 不是 malloc_free 的包装
c++·人工智能·算法
故事和你9111 小时前
洛谷-【动态规划1】动态规划的引入2
开发语言·数据结构·c++·算法·动态规划·图论
重生之我是Java开发战士11 小时前
【动态规划】背包问题:完全背包,二位费用的背包问题,似包非包
算法·动态规划