【做题笔记】树形 dp
Solve
设计状态 \(dp[i]\) 表示子树 \(i\) 的最大点权和,则有:
- 当 \(dp[son[i]] > 0\) 时,选以 \(son[i]\) 为根的子树肯定优;
- 当 \(dp[son[i]] < 0\) 时,选以 \(son[i]\) 为根的子树肯定不优;
因此,转移方程为:
$dp[i] = \sum\limits_{a[son[i]]>0} dp[son[i]] + a[i]$
时间复杂度 \(O(n)\)
答案为 \(\max\limits_{1\le i \le n} dp[i]\)。
Code
#include <bits/stdc++.h>
#define ll long long
#define H 19260817
#define rint register int
#define For(i,l,r) for(rint i=l;i<=r;++i)
#define FOR(i,r,l) for(rint i=r;i>=l;--i)
#define MOD 1000003
#define mod 1000000007
using namespace std;
inline int read() {
rint x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
void print(int x){
if(x<0){putchar('-');x=-x;}
if(x>9){print(x/10);putchar(x%10+'0');}
else putchar(x+'0');
return;
}
const int N = 16100;
int n, a[N], f[N], ans = -0x3f3f3f3f;
vector<int> e[N];
void dfs(int x, int fa) {
f[x] = a[x];
for (int i = 0; i < e[x].size(); i++) {
int y = e[x][i];
if(y == fa) continue;
dfs(y, x);
if(f[y] > 0) f[x] += f[y];
}
}
signed main() {
n = read();
For(i,1,n) a[i] = read();
For(i,1,n-1) {
int u = read(), v = read();
e[u].push_back(v);
e[v].push_back(u);
}
dfs(1, 0);
For(i,1,n) ans = max(ans, f[i]);
cout << ans << '\n';
return 0;
}
Solve
设计状态 \(dp[i][0/1]\) 表示在 \(i\) 子树内, 放/不放 第 \(i\) 个节点使其合法所需的最少的士兵数目。则有:
- 不选 \(i\) 节点,则 \(i\) 的儿子必须选;
- 选 \(i\) 节点,则 \(i\) 的儿子可选可不选;
因此,转移方程为:
$dp[i][0] = \sum dp[son[i]][1]$
\(dp[i][1] = \sum \min(dp[son[i]][0], dp[son[i]][1])\)
时间复杂度 \(O(n)\)。
答案为 \(min(dp[0][0], dp[0][1])\)。(以 \(0\) 为根)
Code
#include <bits/stdc++.h>
#define int long long
#define H 19260817
#define rint register int
#define For(i,l,r) for(rint i=l;i<=r;++i)
#define FOR(i,r,l) for(rint i=r;i>=l;--i)
#define MOD 1000003
#define mod 1000000007
using namespace std;
inline int read() {
rint x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
void print(int x){
if(x<0){putchar('-');x=-x;}
if(x>9){print(x/10);putchar(x%10+'0');}
else putchar(x+'0');
return;
}
const int N = 1e5;
vector<int> e[N];
int n, f[N][2];
void dfs(int x, int fa) {
f[x][0] = f[x][1] = 0;
for (int i = 0; i < e[x].size(); i++) {
int y = e[x][i];
if(y == fa) continue;
dfs(y, x);
f[x][0] += f[y][1];
f[x][1] += min(f[y][0], f[y][1]);
}
f[x][1]++;
}
signed main() {
n = read();
For(i,1,n) {
int x = read(), k = read();
For(j,1,k) {
int y = read();
e[x].push_back(y);
e[y].push_back(x);
}
}
dfs(0, -1);
cout << min(f[0][0], f[0][1]) << '\n';
return 0;
}
/*
8
0 2 1 2
1 2 3 4
2 0
3 0
4 1 5
5 2 6 7
6 0
7 0
*/
【做题笔记】树形 dp的更多相关文章
- SAM 做题笔记(各种技巧,持续更新,SA)
SAM 感性瞎扯. 这里是 SAM 做题笔记. 本来是在一篇随笔里面,然后 Latex 太多加载不过来就分成了两篇. 标 * 的是推荐一做的题目. trick 是我总结的技巧. I. P3804 [模 ...
- SDOI2016 R1做题笔记
SDOI2016 R1做题笔记 经过很久很久的时间,shzr终于做完了SDOI2016一轮的题目. 其实没想到竟然是2016年的题目先做完,因为14年的六个题很早就做了四个了,但是后两个有点开不动.. ...
- POI做题笔记
POI2011 Conspiracy (2-SAT) Description \(n\leq 5000\) Solution 发现可拆点然后使用2-SAT做,由于特殊的关系,可以证明每次只能交换两个集 ...
- C语言程序设计做题笔记之C语言基础知识(下)
C 语言是一种功能强大.简洁的计算机语言,通过它可以编写程序,指挥计算机完成指定的任务.我们可以利用C语言创建程序(即一组指令),并让计算机依指令行 事.并且C是相当灵活的,用于执行计算机程序能完成的 ...
- C语言程序设计做题笔记之C语言基础知识(上)
C语言是一种功能强大.简洁的计算机语言,通过它可以编写程序,指挥计算机完成指定的任务.我们可以利用C语言创建程序(即一组指令),并让计算机依指令行事.并且C是相当灵活的,用于执行计算机程序能完成的几乎 ...
- SDOI2017 R1做题笔记
SDOI2017 R1做题笔记 梦想还是要有的,万一哪天就做完了呢? 也就是说现在还没做完. 哈哈哈我竟然做完了-2019.3.29 20:30
- SDOI2014 R1做题笔记
SDOI2014 R1做题笔记 经过很久很久的时间,shzr又做完了SDOI2014一轮的题目. 但是我不想写做题笔记(
- LCT做题笔记
最近几天打算认真复习LCT,毕竟以前只会板子.正好也可以学点新的用法,这里就用来写做题笔记吧.这个分类比较混乱,主要看感觉,不一定对: 维护森林的LCT 就是最普通,最一般那种的LCT啦.这类题目往往 ...
- java做题笔记
java做题笔记 1. 初始化过程是这样的: 1.首先,初始化父类中的静态成员变量和静态代码块,按照在程序中出现的顺序初始化: 2.然后,初始化子类中的静态成员变量和静态代码块,按照在程序中出现的顺序 ...
- HNOI2015做题笔记
HNOI2015 亚瑟王(概率DP) 根据期望的线性性,我们只需要算出每一种卡牌触发的概率就可以算出期望的值 考虑与第\(i\)张卡牌触发概率相关的量,除了\(p_i\)还有前\(i-1\)张卡牌中触 ...
随机推荐
- 深度学习04-(Tensorflow简介、图与会话、张量基本操作、Tensorboard可视化、综合案例:线性回归)
深度学习04-Tensorflow 深度学习04-(Tensorflow) Tensorflow概述 Tensorflow简介 什么是Tensorflow Tensorflow的特点 Tensorfl ...
- Django笔记三十三之缓存操作
本文首发于公众号:Hunter后端 原文链接:Django笔记三十三之缓存操作 这一节介绍一下如何在 Django 中使用 redis 做缓存操作. 在 Django 中可以有很多种方式做缓存,比如数 ...
- elSelect点击空白处无法收起下拉框(失去焦点并隐藏)
学习记录,为了以后有同样的问题,省得再百度了,方便自己也方便你们element 中多选的select 有个问题,就是点击空白或者关闭弹窗,下拉还会一直展示出来百度了好一会,觉得下面两位大佬说的最合理, ...
- 通过Serverless私有化部署ChatGPT Web
作为开发人员,想要自己部署一个渠道访问或是想随时访问但是奈何魔法有限,又或是海外服务器太贵,不想耗费这个钱,本文借助 Serverless 来搭建一下私有 ChatGPT 服务,Serverless ...
- 2022-04-18:things是一个N*3的二维数组,商品有N件,商品编号从1~N, 比如things[3] = [300, 2, 6], 代表第3号商品:价格300,重要度2,它是6号商品的附属
2022-04-18:things是一个N3的二维数组,商品有N件,商品编号从1~N, 比如things[3] = [300, 2, 6], 代表第3号商品:价格300,重要度2,它是6号商品的附属商 ...
- 2022-01-02:给定两个数组A和B,长度都是N, A[i]不可以在A中和其他数交换,只可以选择和B[i]交换(0<=i<n), 你的目的是让A有序,返回你能不能做到。
2022-01-02:给定两个数组A和B,长度都是N, A[i]不可以在A中和其他数交换,只可以选择和B[i]交换(0<=i<n), 你的目的是让A有序,返回你能不能做到. 答案2022- ...
- 2021-08-10:给定一个正数数组arr,返回arr的子集不能累加出的最小正数。1)正常怎么做? 2)如果arr中肯定有1这个值,怎么做?
2021-08-10:给定一个正数数组arr,返回arr的子集不能累加出的最小正数.1)正常怎么做? 2)如果arr中肯定有1这个值,怎么做? 福大大 答案2021-08-10: 先排序,然后扩充ra ...
- Python Numpy 切片和索引(高级索引、布尔索引、花式索引)
张量(Tensor).标量(scalar).向量(vector).矩阵(matrix) Python Numpy 切片和索引(高级索引.布尔索引.花式索引) Python NumPy 广播(Broad ...
- 技术招聘漫谈 | 正在招Golang工程师的你,赶快收藏这份识人秘籍!
各位技术面试官,欢迎来到新一期的技术招聘漫谈专栏. 在前两期的专栏中,我们解析了前端工程师以及 Java 工程师 这两个常见技术岗位的招聘技巧. 今天,我们想把目光聚焦在一个前景与"钱&qu ...
- Windows AD域查询属性-密码过期时间
Windows AD域查询属性-密码过期时间 Windows PowerShell命令方式查询: net user zhou /domain找出 SamAccountName 的值为zhou的用户部分 ...