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;
}
相关推荐
lxh01131 分钟前
最长有效括号
数据结构·算法
橙子牛奶糖5 分钟前
Science | 本周最新文献速递
算法·gwas·生物信息学·单细胞测序
皮卡蛋炒饭.8 分钟前
背包问题Ⅱ与二分问题
算法
Code Slacker11 分钟前
LeetCode Hot100 —— 普通数组(面试纯背版)(五)
数据结构·c++·算法·leetcode·面试
sin_hielo13 分钟前
leetcode 3573(买卖股票问题,状态机dp)
数据结构·算法·leetcode
flashlight_hi27 分钟前
LeetCode 分类刷题:110. 平衡二叉树
javascript·算法·leetcode
式51628 分钟前
线性代数(九)线性相关性、基与维数
线性代数·算法·机器学习
啊阿狸不会拉杆28 分钟前
《数字图像处理》第7章:小波变换和其他图像变换
图像处理·人工智能·python·算法·机器学习·计算机视觉·数字图像处理
炽烈小老头29 分钟前
【 每天学习一点算法 2025/12/17】验证二叉搜索树
学习·算法
用户2719953721335 分钟前
基于Label Studio 集成视觉大模型Qwen2-VL和yolo实现自动标注
算法