P1352 没有上司的舞会[树形dp]
题目描述
某大学有N个职员,编号为1~N。他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司。现在有个周年庆宴会,宴会每邀请来一个职员都会增加一定的快乐指数Ri,但是呢,如果某个职员的上司来参加舞会了,那么这个职员就无论如何也不肯来参加舞会了。所以,请你编程计算,邀请哪些职员可以使快乐指数最大,求最大的快乐指数。
输入输出格式
输入格式:
第一行一个整数N。(1<=N<=6000)
接下来N行,第i+1行表示i号职员的快乐指数Ri。(-128<=Ri<=127)
接下来N-1行,每行输入一对整数L,K。表示K是L的直接上司。
最后一行输入0 0
输出格式:
输出最大的快乐指数。
输入输出样例
输入样例#1:
7
1
1
1
1
1
1
1
1 3
2 3
6 4
7 4
4 5
3 5
0 0
输出样例#1:
5
解析:
这是一道相当经典的树形dp入门题。
树形\(dp\),顾名思义,就是在树这种数据结构上做\(dp\),所以要学习树形\(dp\),首先要学习树的储存结构和遍历方法。
显然,在这道题中,我们可以以树的深度作为阶段,用某个人的以他为根的子树的最优解作为状态,决策就是某个人来与不来。
那岂不就是直接开一个一维数组\(dp[]\)来做就得了?
其实不然。
我们会发现这样做忽略了在做当前决策时,之前做过的决策实际上是会当前决策影响的。
考虑如下情形:如果一个人的上司来了,那么他只有不来一种选择;如果一个人的上司没来,那么他既可以来也可以不来。然后这个人的决策又会影响到他的下属,继而传播到整颗子树。
因此,这道题是有后效性的。
不急,对于这种情况,我们再加一维把任意一个人来与不来的情况分开记录,就不会使最优解互相影响了。
假设\(dp[i][1]\)表示第\(i\)个人当前如果来的话的最优解,\(dp[i][0]\)就表示第\(i\)个人不来时的最优解。
初始化就是对于任意的一个人\(i\),有\(dp[i][0]=0,dp[i][1]=w[i]\),其中\(w[i]\)表示这个人的嗑嗨指数。
状态转移方程:
{dp[i][0]=\sum_{j \epsilon son(i)} max(dp[j][0],dp[j][1])}
\]
我们可以\(dfs\)一遍整棵树,在向下递归时初始化,向上递归时做\(dp\)。
参考代码:
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#define ri register int
const int N=6010;
const int INF=0x3f3f3f3f;
using namespace std;
inline int read()
{
    int f=1,x=0;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
struct rec{
    int next,ver;
}g[N<<1];
int head[N],tot,n,w[N];
int dp[N][2];
bool v[N],fa[N];
void add(int x,int y)
{
    g[++tot].ver=y;
    g[tot].next=head[x],head[x]=tot;
}
void calc(int x)
{
    v[x]=1;
    dp[x][0]=0;
    dp[x][1]=w[x];
    for(ri i=head[x];i;i=g[i].next){
        int y=g[i].ver;
        if(v[y]==1) continue;
        calc(y);
        dp[x][0]+=max(dp[y][1],dp[y][0]);
        dp[x][1]+=dp[y][0];
    }
}
int main()
{
    n=read();
    for(ri i=1;i<=n;i++) w[i]=read();
    int x,y;
    for(ri i=1;i<n;i++){
        x=read(),y=read();
        add(y,x);fa[x]=1;
    }
    getchar();getchar();
    int root;
    for(ri i=1;i<=n;i++){
        if(!fa[i]){
            root=i;
            break;
        }
    }
    calc(root);
    cout<<max(dp[root][1],dp[root][0])<<endl;
    return 0;
}
												
											P1352 没有上司的舞会[树形dp]的更多相关文章
- 洛谷P1352 没有上司的舞会——树形DP
		
第一次自己写树形DP的题,发个博客纪念`- 题目来源:P1352 没有上司的舞会 题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结 ...
 - P1352 没有上司的舞会——树形DP入门
		
P1352 没有上司的舞会 题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司.现在有个周年庆宴会,宴会每邀请来一个职员 ...
 - P1352 没有上司的舞会&&树形DP入门
		
https://www.luogu.com.cn/problem/P1352 题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的 ...
 - [luogu]P1352 没有上司的舞会[树形DP]
		
本Lowbee第一次写树形DP啊,弱...一个变量写错半天没看出来...... 题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点 ...
 - 洛谷 P1352 没有上司的舞会  树形DP板子
		
luogu传送门 题目描述: 某大学有n个职员,编号为1~n. 他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司. 现在有个周年庆宴会,宴会每邀请来一个职员都会 ...
 - 洛谷 P1352 没有上司的舞会(树形 DP)
		
题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司.现在有个周年庆宴会,宴会每邀请来一个职员都会增加一定的快乐指数Ri, ...
 - 『没有上司的舞会 树形DP』
		
树形DP入门 有些时候,我们需要在树形结构上进行动态规划来求解最优解. 例如,给定一颗\(N\)个节点的树(通常是无根树,即有\(N-1\)条无向边),我们可以选择任意节点作为根节点从而定义出每一颗子 ...
 - CodeVS1380 没有上司的舞会 [树形DP]
		
题目传送门 没有上司的舞会 题目描述 Description Ural大学有N个职员,编号为1~N.他们有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司.每个职员有一个 ...
 - 没有上司的舞会 树形dp
		
题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司.现在有个周年庆宴会,宴会每邀请来一个职员都会增加一定的快乐指数Ri, ...
 
随机推荐
- Django:bootstrap table自定义查询实现
			
参考:https://jalena.bcsytv.com/archives/tag/bootstrap 背景: bootstrap table在客户端分页方式下,自带有简易的搜索功能,但是功能太单一, ...
 - Vue简单基础 + 实例 及 组件通信
			
vue的双向绑定原理:Object.defineProperty() vue实现数据双向绑定主要是:采用数据劫持结合发布者-订阅者模式的方式,通过 Object.defineProperty() 来劫 ...
 - Java基础:类文件结构及类加载
			
Class文件结构 魔数 4bits 确定该文件是否是可接受的Class文件(0xCAFEBABE) 版本号 4bits 包括次版本号和主版本号 常量池 包括字面量(文本字符串,声明为final的常量 ...
 - 模型-视图-控制器的C++解释
			
模型-视图-控制器 (MVC) 并非一种技术,而是软件设计/工程的一个概念.MVC包含三个组成部分,如下图所示 模型 模型直接响应对数据的处理,比如数据库.模型不应依赖其它组成部分,即视图或控制器,换 ...
 - 微信小程序 与后台交互----传递和回传时间
			
wxml代码 <!--index.wxml--> <view class="container"> <view class="section ...
 - tomcat 启动闪退解决方法
			
当我们在windows上面进行项目的部署与启动的时候有的时候tomcat在进行启动的时候会删一下就退了,这个时候一般是里面启动的时候设置的jdk的问题下面咱们来看一下具体解决方案 编辑我们的start ...
 - 按键板的原理与实现----ADC
			
在嵌入式系统产品开发中,按键板的设计是最基本的,也是项目评估阶段必须要考虑的问题.其实现方式又很多种,具体使用那一种就需要结合特定IC的可用IO数量,并综合考虑成本,做出最终选择.本系列文章将介绍多种 ...
 - 谈谈redis的热key问题如何解决
			
引言 讲了几天的数据库系列的文章,大家一定看烦了,其实还没讲完...(以下省略一万字).今天我们换换口味,来写redis方面的内容,谈谈热key问题如何解决.其实热key问题说来也很简单,就是瞬间有几 ...
 - LeetCode 230. 二叉搜索树中第K小的元素(Kth Smallest Element in a BST)
			
230. 二叉搜索树中第K小的元素 230. Kth Smallest Element in a BST 题目描述 给定一个二叉搜索树,编写一个函数 kthSmallest 来查找其中第 k 个最小的 ...
 - models环境配置和表查询
			
一般操作 在进行一般操作时先配置一下参数,使得我们可以直接在Django页面中运行我们的测试脚本 在Python脚本中调用Django环境 模型转为mysql数据库中的表settings配置 需要在s ...