树形dp 之 小胖守皇宫
题目描述
huyichen世子事件后,xuzhenyi成了皇上特聘的御前一品侍卫。
皇宫以午门为起点,直到后宫嫔妃们的寝宫,呈一棵树的形状;有边相连的宫殿间可以互相望见。大内保卫森严,三步一岗,五步一哨,每个宫殿都要有人全天候看守,在不同的宫殿安排看守所需的费用不同。
可是xuzhenyi手上的经费不足,无论如何也没法在每个宫殿都安置留守侍卫。
帮助xuzhenyi布置侍卫,在看守全部宫殿的前提下,使得花费的经费最少。
输入输出格式
输入格式
输入文件中数据表示一棵树,描述如下:
第1行\(n\),表示树中结点的数目。
第2行至第\(n+1\)行,每行描述每个宫殿结点信息,依次为:该宫殿结点标号\(i(0<i<=n)\),在该宫殿安置侍卫所需的经费\(k\),该边的儿子数\(m\),接下来\(m\)个数,分别是这个节点的\(m\)个儿子的标号\(r_1,r_2,...,r_m\)。
对于一个\(n(0 < n <= 1500)\)个结点的树,结点标号在\(1\)到\(n\)之间,且标号不重复。
输出格式
输出文件仅包含一个数,为所求的最少的经费。
样例
样例输入
6
1 30 3 2 3 4
2 16 2 5 6
3 5 0
4 4 0
5 11 0
6 5 0
样例输出
25
题解
当我们分析一个节点的时候,很容易想到起码有两种情况:在这个节点设侍卫或者不设。但是如果单纯地只是分析它不设,那么依据题意,它必须得被观测到,那么它的子节点到底要不要设呢?此时便又要分两种情况:被儿子观测或是被父亲观测。因此到这里我们把这个题已经抽象成了三种状态转移:
\(f[i][1]\)表示在\(i\)节点的子节点设一个侍卫的最小经费(默认\(i\)节点自己不设)
\(f[i][2]\)表示在\(i\)节点设一个侍卫的最小经费
\(f[i][3]\)表示在\(i\)节点的父节点设一个侍卫的最小经费(默认\(i\)节点自己不设)
1、\(f[i][1]\)表示i节点被它的子节点观测到,这时我们就要考虑:是不是子节点一定会再自己那里设一个观测点呢?当然不一定了,当且仅当子节点 \(f[son[i]][2]<f[son[i]][1]\)时,他才会在自己那里设。那么我们就需要找遍i的所有儿子,只要有一个儿子可以设就行了。这个怎么实现呢?我们只需先把所有儿子的\(min(f[v][1],f[v][2])\)累加到\(f[i][1]\)上,再取所有儿子的\(f[v][2]-min(f[v][1],f[v][2])\)最小值\(t\),如果这个最小值\(t\)不是0,就说明没有一个儿子打算在自己那里设点,就必须强迫一个儿子改变最优解,来满足i节点的需求,即用\(f[i][2]\)加上\(t\),若\(t\)是0,不影响,加上也无妨。
f[i][1]+=min(f[v][1],f[v][2]);//既然默认自己不会设点,就不可能有f[v][3]这个状态
f[i][1]+=t;
- 2、\(f [ i ] [ 2 ]\) 表示\(i\)节点自己那里设了一个侍卫,既然自己已经设了一个,那么子节点的三种情况都要考虑。
f[i][2]+=min(f[v][1],f[v][2],f[v][3]);
- 3、\(f [ i ] [ 3 ]\) 表示\(i\)节点被它的父节点观测到,那么除了\(f [ v ] [ 3 ]\)要被排除掉,其他的只要保证子节点可以被观测到即可。
f[i][3]+=min(f[v][1],f[v][2]);
代码
下面是参考代码:
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=1500+50,
INF=0x3f3f3f3f;
vector<int> son_id[maxn];
int f[maxn][4],//树形dp : 1=>son 2=>itself 3=>father
cnt[maxn],//出现次数
son_num[maxn],//儿子数目
cost[maxn];//所需的经费
int n;
void tree_dp(int x){
int ans=INF;
for(int i=0;i<son_num[x];i++){
int son=son_id[x][i];
tree_dp(son);
f[x][1]+=min(f[son][1],f[son][2]);
ans=min(ans,f[son][2]-min(f[son][1],f[son][2]));
f[x][2]+=min(f[son][1],min(f[son][2],f[son][3]));
f[x][3]+=min(f[son][1],f[son][2]);
}
f[x][1]+=ans;
f[x][2]+=cost[x];
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
int id;
cin>>id;
cin>>cost[id]>>son_num[id];
for(int j=1;j<=son_num[id];j++){
int x;cin>>x;
cnt[x]++;
son_id[id].push_back(x);
}
}
for(int i=1;i<=n;i++)
if(cnt[i]==0){
tree_dp(i);
cout<<min(f[i][1],f[i][2]);
}
return 0;
}
树形dp 之 小胖守皇宫的更多相关文章
- Vijos 1144 小胖守皇宫 【树形DP】
小胖守皇宫 描述 huyichen世子事件后,xuzhenyi成了皇上特聘的御前一品侍卫. 皇宫以午门为起点,直到后宫嫔妃们的寝宫,呈一棵树的形状:某些宫殿间可以互相望见.大内保卫森严,三步一岗,五步 ...
- 【树形dp】vijos1144小胖守皇宫
细节很精妙 描述 huyichen世子事件后,xuzhenyi成了皇上特聘的御前一品侍卫. 皇宫以午门为起点,直到后宫嫔妃们的寝宫,呈一棵树的形状:某些宫殿间可以互相望见.大内保卫森严,三步一岗,五步 ...
- [vijos1144]小胖守皇宫<树形dp>
题目链接:https://vijos.org/p/1144 woc我竟然A了,这道经典的树形dp或者说是树形dp的入门题我终于过了,虽然之前做过一些树形dp的题,但是这题开始还是一脸懵逼,dp方程如何 ...
- 小胖守皇宫(VIJOS P1144 )题解
题目描述 huyichen世子事件后,xuzhenyi成了皇上特聘的御前一品侍卫. 皇宫以午门为起点,直到后宫嫔妃们的寝宫,呈一棵树的形状:某些宫殿间可以互相望见.大内保卫森严,三步一岗,五步一哨,每 ...
- vijos 小胖守皇宫
点击打开题目 树形DP 显然会想到某个点放或不放守卫来定义状态,但在不放的情况下,需要分类讨论是父亲放还是一个儿子放,于是定义以下状态: f[root][0]表示自己不放,父亲也不放 f[root][ ...
- Vijos1144小胖守皇宫【树形DP】
皇宫看守 太平王世子事件后,陆小凤成了皇上特聘的御前一品侍卫.皇宫以午门为起点,直到后宫嫔妃们的寝宫,呈一棵树的形状:某些宫殿间可以互相望见.大内保卫森严,三步一岗,五步一哨,每个宫殿都要有人全天候看 ...
- 【vijos1144】小胖守皇宫(树形DP)
描述 huyichen世子事件后,xuzhenyi成了皇上特聘的御前一品侍卫. 皇宫以午门为起点,直到后宫嫔妃们的寝宫,呈一棵树的形状:某些宫殿间可以互相望见.大内保卫森严,三步一岗,五步一哨,每个宫 ...
- vijos1144(小胖守皇宫)
也是ural1039 描述 huyichen世子事件后,xuzhenyi成了皇上特聘的御前一品侍卫. 皇宫以午门为起点,直到后宫嫔妃们的寝宫,呈一棵树的形状:某些宫殿间可以互相望见.大内保卫森严,三步 ...
- 树形DP 复习
树形DP 树形DP:建立在树上的动态规划 一般有两种传递方式:根→叶或叶→根 前者出现在换根DP中,一般操作是求出某一个点的最优解,再通过这一个点推知其他点的最优解. 后者是树形DP的常见形式,一般树 ...
随机推荐
- Web前端 -- Webpack
一.Webpack Webpack 是一个前端资源加载/打包工具.它将根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源. 二.Webpack安装 1.全局安装 npm i ...
- 用 npm 搭建vue项目
一.开发环境 vue推荐开发环境: Node.js: javascript运行环境(runtime),不同系统直接运行各种编程语言 npm: Nodejs下的包管理器. webpack: 它主要的用途 ...
- 黑马程序员spring data jpa 2019年第一版本
第一步首先创建一个maven工程,导入对于的pom依赖 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xs ...
- 2020/6/10 JavaScript高级程序设计 BOM
BOM(浏览器对象模型):提供用于访问浏览器的对象. 8.1 window对象 window是BOM的核心对象,表示浏览器的一个实例. JavaScript访问浏览器窗口的接口 ECMAScript规 ...
- MySQL高级用法
-- 关联查询-- select * from Goods_BomItems s,Goods_Bom t where t.GoodsBomId = s.GoodsBomId and t.GoodsBo ...
- GitLab Runner部署(kubernetes环境)
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- python实用笔记——IO编程
打开文件 f = open('/Users/michael/test.txt', 'r') 再读取 >>> f.read() 'Hello, world!' 最后关闭 >> ...
- 聊聊Java中的异常及处理
前言 在编程中异常报错是不可避免的.特别是在学习某个语言初期,看到异常报错就抓耳挠腮,常常开玩笑说编程1分钟,改bug1小时.今天就让我们来看看什么是异常和怎么合理的处理异常吧! 异常与error介绍 ...
- steam夏日促销悄然开始,用Python爬取排行榜上的游戏打折信息
前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 不知不觉,一年一度如火如荼的steam夏日促销悄然开始了.每年通过大大小小 ...
- cin cout 的优化(神优化)外号:神读入
在比赛里,经常出现数据集超大造成 cin TLE的情况.这时候大部分人(包括原来我也是)认为这是cin的效率不及scanf的错,甚至还上升到C语言和C++语言的执行效率层面的无聊争论.其实像上文所说, ...