caioj 1111 树形动态规划(TreeDP)6: 皇宫看守 (状态设计)
这道题的难点在于状态怎么设计
这道题要求全部都是安全的,所以我们做的时候自底向上每一个结点都要是安全的
结合前一题当前结点选和不选,我们可以分出四种情况出来
选 安全
选 不安全
不选 安全
不选 不安全
显然选 不安全是不可能的,那么就去掉
所以我们就可以设计状态为表示i放人且安全
表示i不放人且安全
表示i不放人且不安全
那么状态转移方程最关键的就是怎么保证回溯的时候都是安全的。
我们只考虑以u为结点的子树,不考虑i的父亲
我们要让u的子树除了u以外全部是安全的,u自己安全和不安全分开讨论
对于 , u放人且安全
那么显然这时儿子无论如何都是安全的(就算原来他是不安全的)
那么有
这里v是u的儿子,这时三种情况都可以,取最小
对于 i不放人且不安全
那么为了保证u不安全肯定儿子不能放人,而这时我们要保证
儿子都安全,所以
对于 i不放人且安全
儿子一定要安全的话有
但是要保证u安全,v中至少有一个放人
这就比较麻烦了,我们要专门来判断v中有没有放人
如果没有的话,就加上
也就是以最小的费用使一个儿子从不放人到放人
最后还有一个小细节,之前我写树形dp搜到叶子都直接return的
这里不行,因为这时是不存在的(不考虑u的父亲)
所以这时要把初始化为最大值(代码中体现为最后加上
)
#include<cstdio>
#include<vector>
#include<algorithm>
#define REP(i, a, b) for(int i = (a); i < (b); i++)
using namespace std;
const int MAXN = 2123;
int f[3][MAXN], a[MAXN], b[MAXN], n;
vector<int> g[MAXN];
void dfs(int u)
{
f[0][u] = a[u];
f[1][u] = f[2][u] = 0;
int mint = 1e8, ok = 0;
REP(i, 0, g[u].size())
{
int v = g[u][i];
dfs(v);
f[0][u] += min(f[0][v], min(f[1][v], f[2][v]));
f[1][u] += min(f[0][v], f[1][v]);
if(f[0][v] <= f[1][v]) ok = 1;
mint = min(mint, f[0][v] - f[1][v]);
f[2][u] += f[1][v];
}
if(!ok) f[1][u] += mint;
}
int main()
{
scanf("%d", &n);
REP(i, 1, n + 1)
{
int u, k, son;
scanf("%d", &u);
scanf("%d%d", &a[u], &k);
REP(j, 0, k)
{
scanf("%d", &son);
g[u].push_back(son);
b[son] = 1;
}
}
REP(i, 1, n + 1)
if(!b[i])
{
dfs(i);
printf("%d\n", min(f[0][i], f[1][i]));
break;
}
return 0;
}
caioj 1111 树形动态规划(TreeDP)6: 皇宫看守 (状态设计)的更多相关文章
- caioj 1114 树形动态规划(TreeDP)3.0:多叉苹果树【scy改编ural1018二叉苹果树】
一波树上背包秒杀-- #include<cstdio> #include<cstring> #include<algorithm> #include<vect ...
- caioj 1112 树形动态规划(TreeDP)7:战略游戏
这道题和上一道题非常相似 这道题是看边,上一道是看点. 但是状态定义不同 看边的话没有不放不安全这种状态 因为当前结点的父亲无法让这颗子树没有看到的边看到 所以这种状态不存在 而上一道题存在不放不安全 ...
- 洛谷 P1273 有线电视网 && caioj 1109 树形动态规划(TreeDP)4:比赛转播(树上分组背包总结)
从这篇博客往前到二叉苹果树都可以用分组背包做 这依赖性的问题,都可以用于这道题类似的方法来做 表示以i为根的树中取j个节点所能得的最大价值 那么每一个子树可以看成一个组,每个组里面取一个节点,两个节点 ...
- 洛谷 P2014 选课 && caioj 1108 树形动态规划(TreeDP)3:选课
这里的先后关系可以看成节点和父亲的关系 在树里面,没有父亲肯定就没有节点 所以我们可以先修的看作父亲,后修的看作节点 所以这是一颗树 这题和上一道题比较相似 都是求树上最大点权和问题 但这道题是多叉树 ...
- caioj 1106 树形动态规划(TreeDP)1:加分二叉树
解这道题的前提是非常熟悉中序遍历的方式 我就是因为不熟悉而没有做出来 中序遍历是5 7 1 2 10的话,如果1是根节点 那么5 7 1就是1的左子树,2, 10就是右子树 这就有点中链式dp的味道了 ...
- 1113: [视频]树形动态规划(TreeDP)8:树(tree)(树形dp状态设计总结)
根据最近做的几道树形dp题总结一下规律.(从这篇往前到洛谷 P1352 ) 这几道题都是在一颗树上,然后要让整棵树的节点或边 满足一种状态.然后点可以影响到相邻点的这种状态 然后求最小次数 那么要从两 ...
- 【ACM/ICPC2013】树形动态规划专题
前言:按照计划,昨天应该是完成树形DP7题和二分图.最大流基础专题,但是由于我智商实在拙计,一直在理解树形DP的思想,所以第二个专题只能顺延到今天了.但是昨天把树形DP弄了个5成懂我是很高兴的!下面我 ...
- 【题解】保安站岗[P2458]皇宫看守[LOJ10157][SDOI2006]
[题解]保安站岗[P2458]皇宫看守[LOJ10157][SDOI2006] 传送门:皇宫看守\([LOJ10157]\) 保安站岗 \([P2458]\) \([SDOI2006]\) [题目描述 ...
- 蓝桥杯 ALGO-4 结点选择 (树形动态规划)
问题描述 有一棵 n 个节点的树,树上每个节点都有一个正整数权值.如果一个点被选择了,那么在树上和它相邻的点都不能被选择.求选出的点的权值和最大是多少? 输入格式 第一行包含一个整数 n . 接下来的 ...
随机推荐
- Sql Server 2012数据库的安装【自己一点一点敲的】
Sql Server 2012数据库的安装 1.到微软官网上下载 下载链接为:https://www.microsoft.com/zh-cn/download/details.aspx?id=2906 ...
- Android Fragment中调用getActivity为null的问题
在使用fragment的时候经常会遇到getActivity()为null的情况.比如我在一个异步网路请求的回调中调用了getActivity()就会出现空指针问题.之前解决这个问题,通常都是直 ...
- angular 报错笔记
1.错误信息: Failed to instantiate module app due to: Error: [$injector:unpr] http://errors.angularjs.org ...
- python的数据类型转换
#编码:#py3中只有2种数据类型:str , bytes# str: unicode形式# bytes: 16进制 (更底层) 有utf8,gbk,gb2312 等等类型 #s='hi 范' # 编 ...
- swift语言点评二
一.数据类型 1.基础类型的封装 Swift provides its own versions of all fundamental C and Objective-C types, includi ...
- 爬虫来啦!Day91
# 一.爬虫# 1.基本操作# 排名爬虫刷票# 抽屉网的所有发布新闻点赞# 自动化程序模拟用于的日常操作# 投票的机制是利用cookies,禁用cookies模式# 自定义的异步IO模块就是Socke ...
- BZOJ 2565 最长双回文串(回文自动机)
题意 给一个长度为N的字符串S.对于一个字符串AB,如果A和B都是回文串,那么称AB是一个双回文串.求问S最长双回文子串的长度?N <= 100000 题解 正反双向构造回文自动机,得到某一个点 ...
- 越努力越幸运--3-日常bug修复
提供一个so给PYTHON调用,后端发现业务处理流程不是按照方法传入的参数来跑. 查看c的代码,看了客户端没看出什么问题,查看服务端为什么会出现这样的情况,有些字段明显不是入参带过来的,跟踪服务端解析 ...
- Python学习————列表的增删改查
增加:li.append(对象):追加 注:print(li.append())--->是Noneli.insert(索引,对象):插入到相应位置li.extend(对象):可迭代的添加到尾部, ...
- 2019年北航OO第二单元(多线程电梯任务)总结
一.三次作业总结 1. 说在前面 对于这次的这三次电梯作业,我采用了和几乎所有人都不同的架构:将每个人当作一个线程.这样做有一定的好处:它使得整个问题的建模更加自然,并且在后期人员调度变得复杂时,可以 ...