【做题笔记】树形 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\)张卡牌中触 ...
随机推荐
- Linux tinyhttpd编译总结
编译环境:ubuntu16.04 x64 直接make编译tinyhttpd弹出如下错误和打印信息 其中报出两个错误信息,一个是cannot find -lsocket,另外一个就是pthread_ ...
- [OpenCV-Python] 10 图像上的算术运算
文章目录 OpenCV-Python: 核心操作 10 图像上的算术运算 10.1 图像加法 10.2 图像混合 10.3 按位运算 OpenCV-Python: 核心操作 10 图像上的算术运算 目 ...
- 一文掌握ArrayList和LinkedList源码解读
大家好,我是Leo! 今天来看一下ArrayList和LinkedList的源码,主要是看一下常用的方法,包括像add.get.remove方法,大部分都是从源码直接解读的,相信大家读完都会有一定收获 ...
- DFS(深度优先搜索) 总是需要重置 visited 的状态吗?
问题来自 P1902 刺杀大使,在最初的实现中 DFS 中一段代码如下: visited[x2][y2] = true; flag = dfs(v, x2, y2); visited[x2][y2] ...
- 【Linux】sed文本处理及软件管理
软件管理 1.编译安装http2.4,实现可以正常访问 安装编译相关工具包 root@mirror-centos8-p11 ~]# yum install gcc make autoconf apr- ...
- Mysql列转行, group_concat的使用
开始业务的查询的时候碰到一个sql的查询语句问题,主要是 group_concat 之前没用过,现在记录一下怎么用 group_concat 用法, 可以将相同的行组合起来 group_concat( ...
- 数据分析缺失值处理(Missing Values)——删除法、填充法、插值法
缺失值指数据集中某些变量的值有缺少的情况,缺失值也被称为NA(not available)值.在pandas里使用浮点值NaN(Not a Number)表示浮点数和非浮点数中的缺失值,用NaT表示时 ...
- Pyhton F字符串引起的invalid syntax
事发现场 偶然运行到之前写的爬虫,发现运行不了,报错invalid syntax,于是来找bug 报错截图: 原因: 这样用法称之为 f-string f-string,亦称为格式化字符串常量(for ...
- PlayWright(一)
1.如何安装? 安装playwright只需要一条命令,就是pip安装命令,命令如下: pip install playwright 注:playwright需要Python3.7或更新的版本 2.然 ...
- 一文教会你用Apache SeaTunnel Zeta离线把数据从MySQL同步到StarRocks
在上一篇文章中,我们介绍了如何下载安装部署SeaTunnel Zeta服务(3分钟部署SeaTunnel Zeta单节点Standalone模式环境),接下来我们介绍一下SeaTunnel支持的第一个 ...