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;
}
相关推荐
residual_fan22 分钟前
特征级SMOTE(Feature-level SMOTE)论文分享
人工智能·算法·数据挖掘·数据分析
xxwxx__24 分钟前
深入理解 C++ STL:stack、queue 与 deque 从使用到底层实现全解析
开发语言·c++·算法
sylviiiiiia35 分钟前
Leetcode hot100 多数元素/相交链表/反转链表
算法·leetcode·链表
CoderYanger38 分钟前
A.每日一题:3622. 判断整除性
java·程序人生·算法·leetcode·面试·职场和发展·蓝桥杯
rannn_1111 小时前
【力扣hot100】动态规划专题|70、118、198、279、322、139、300、152、416、32
算法·leetcode·动态规划
渡之1 小时前
ArduPilot(APM)滤波器之 HarmonicNotchFilter 深度解析
算法·无人机
我不会起名字3221 小时前
一天一道算法题(26):栈的简单应用
java·数据结构·python·算法·leetcode·golang·
lvwangshu1 小时前
exBSGS 算法
数学·算法
不会就选b1 小时前
算法日常・每日刷题--<贪心+大根堆>2
数据结构·算法
码艺-Alimjan1 小时前
维吾尔语数字转文本
java·javascript·python·算法·go