关于树形DP几道入门题目

今天恶补树形DP,感觉海星。

其实挺简单的。

介绍几道例题,我会的。

1.洛谷P1352 没有上司的舞会

我的一篇题解

我们可以考虑每一个节点都是有两种情况。

一个是被邀请;另一个是不会被邀请。

前者后果就是子节点不可以被选择;

后者结果就是子节点可以被选择。

于是关系明确,状态转移方程为:

dp[root][0] += std::max(dp[son[root][i]][0],dp[son[root][i]][1]);

dp[root][1] += dp[son[root][i]][0];

海星。

son[root][i]是当前节点的儿子。

初始化要记得是每一个点的快乐指数。

#include <cstdio>
#include <iostream>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#define Max 6050
#define re register
std::vector<int>son[Max];
int n,root,dp[Max][2],fa[Max];
void dfs(int root) {
for(re int i = 0 ; i < son[root].size() ; ++ i)
dfs(son[root][i]);
for(re int i = 0 ; i < son[root].size() ; ++ i) {
dp[root][0] += std::max(dp[son[root][i]][0],dp[son[root][i]][1]);
dp[root][1] += dp[son[root][i]][0];
}
}
void init() {
scanf("%d",&n);int u,v;memset(fa,-1,sizeof fa);
for(re int i = 1 ; i <= n ; ++ i) scanf("%d",&dp[i][1]);
for(re int i = 1 ; i < n ; ++ i)
scanf("%d%d",&u,&v),fa[u]=v,son[v].push_back(u);
scanf("%d%d",&u,&v);
}
inline void print(int root) {printf("%d",std::max(dp[root][0],dp[root][1]));}
void work() {
int root=1;
while(fa[root] != -1) root = fa[root];
dfs(root);
print(root);
}
int main() {
init();
work();
return 0;
}

2.poj1463 Strategic game

我们考虑每一个节点有两种情况。

一个是被选择;另一个是不被选择。

前者的结果是他的子节点可以被选择,也可以不被选择;

后者的结果是他的子节点必须备选择。

所以状态转移方程出来了:

dp[root][0] += std::max(dp[son[root][i]][0],dp[son[root][i]][1]);

dp[root][1] += dp[son[root][i]][0];

#include <cstdio>
#include <iostream>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#define Max 1550
#define re register
int n,dp[Max][2],fa[Max];
std::vector<int>son[Max];
void dfs(int root) {
for(re int i = 0 ; i < son[root].size() ; ++ i)
dfs(son[root][i]);
for(re int i = 0 ; i < son[root].size() ; ++ i) {
dp[root][0] += dp[son[root][i]][1];
dp[root][1] += std::min(dp[son[root][i]][0],dp[son[root][i]][1]);
}
}
void print(int root) {printf("%d\n",std::min(dp[root][0],dp[root][1]));}
void work() {
int root=0;
while(fa[root] != -1) root = fa[root];
dfs(root);
print(root);
}
void init() {
int k,x,y;char ch;
while(scanf("%d",&n) != EOF) {
for(re int i = 0 ; i < n ; ++ i)
fa[i] = -1,dp[i][0] = 0,dp[i][1] = 1;
for(re int p = 1 ; p <= n ; ++ p) {
scanf("%d",&k);std::cin >> ch;
std::cin >> ch;scanf("%d",&y);
std::cin >> ch;son[k].clear();
for(re int i = 1 ; i <= y ; ++ i)
scanf("%d",&x),fa[x]=k,son[k].push_back(x);
}
work();
}
}
int main() {
init();
return 0;
}

最新文章

  1. MFC 启动其他程序 变相跳转
  2. [转]一个四叉树Demo学习
  3. 【BZOJ】1098: [POI2007]办公楼biu(补图+bfs+链表)
  4. 清理IOS项目未使用图片脚本
  5. 在生成 Visual c + + 2005年或从 DLL 文件中使用 CString 派生的类的 Visual c + +.net 应用程序时,您可能会收到 LNK2019 错误消息
  6. (java) Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
  7. 六行代码获取本地IP
  8. hdu 5071 Chat(模拟)
  9. Linux核心设计依据(七)系统调用
  10. IP地址和硬件地址 ARP协议
  11. 通过自定义的URL Scheme启动你的App
  12. BZOJ 3697: 采药人的路径 [点分治] [我想上化学课]
  13. 开源框架 ImageLoader +ListView+GridView+RecyclerView 浅解
  14. 向数据库中添加数据,通过se16 不能添加,通过 代码可以添加的原因
  15. 套接字编程,创建套接字socket
  16. js Array 方法总结
  17. Vim实用技巧系列 - 利用百度云和git实现vim配置多机共享
  18. 撩课-Web大前端每天5道面试题-Day28
  19. 【Golang 接口自动化02】使用标准库net/http发送Post请求
  20. Java 中的 JVM、堆和栈 -- 初步了解

热门文章

  1. kubenetes之配置pod的QoS
  2. C#里面如何判断一个Object是否是某种类型
  3. 八.软件自动化和web测试
  4. 使用基础知识完成java小作业?强化练习-1.输入数组计算最大值-2.输出数组反向打印-3.求数组平均值与总和-4.键盘输两int,并求总和-5.键盘输三个int,并求最值;
  5. 【开发笔记】- 将MySQL数据库表中自增ID从0开始
  6. Float型 与 Double型数据的存储方式
  7. Jquery学习笔记,全面实用,需要的可以留下邮箱,给大家发原稿文档
  8. SpringBoot处理全局统一异常
  9. Django之REST_FRAMEWORK 认证组件
  10. 【Idea】idea中spring框架配置文件,无法自动提示spring配置