题目描述

某大学有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][1]+=\sum_{j\epsilon son(i) }{dp[j][0]}},
{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]的更多相关文章

  1. 洛谷P1352 没有上司的舞会——树形DP

    第一次自己写树形DP的题,发个博客纪念`- 题目来源:P1352 没有上司的舞会 题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结 ...

  2. P1352 没有上司的舞会——树形DP入门

    P1352 没有上司的舞会 题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司.现在有个周年庆宴会,宴会每邀请来一个职员 ...

  3. P1352 没有上司的舞会&&树形DP入门

    https://www.luogu.com.cn/problem/P1352 题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的 ...

  4. [luogu]P1352 没有上司的舞会[树形DP]

    本Lowbee第一次写树形DP啊,弱...一个变量写错半天没看出来...... 题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点 ...

  5. 洛谷 P1352 没有上司的舞会 树形DP板子

    luogu传送门 题目描述: 某大学有n个职员,编号为1~n. 他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司. 现在有个周年庆宴会,宴会每邀请来一个职员都会 ...

  6. 洛谷 P1352 没有上司的舞会(树形 DP)

    题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司.现在有个周年庆宴会,宴会每邀请来一个职员都会增加一定的快乐指数Ri, ...

  7. 『没有上司的舞会 树形DP』

    树形DP入门 有些时候,我们需要在树形结构上进行动态规划来求解最优解. 例如,给定一颗\(N\)个节点的树(通常是无根树,即有\(N-1\)条无向边),我们可以选择任意节点作为根节点从而定义出每一颗子 ...

  8. CodeVS1380 没有上司的舞会 [树形DP]

    题目传送门 没有上司的舞会 题目描述 Description Ural大学有N个职员,编号为1~N.他们有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司.每个职员有一个 ...

  9. 没有上司的舞会 树形dp

    题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司.现在有个周年庆宴会,宴会每邀请来一个职员都会增加一定的快乐指数Ri, ...

随机推荐

  1. vue el-table 自适应表格内容宽度

    由于表头和列是分开渲染的,通过el-table 设置fit属性,只能撑开表头,但是没有办法根据列的内容去适应宽度.网上找了一些使用根据表格内容计算表头宽度的文章,记个笔记. 代码逻辑是通过vue  的 ...

  2. 第07组 Alpha冲刺(1/4)

    队名:秃头小队 组长博客 作业博客 组长徐俊杰 过去两天完成的任务:完成人员分配,初步学习Android开发 Github签入记录 接下来的计划:继续完成Android开发的学习,带领团队进行前后端开 ...

  3. solr搜索结果转实体类对象的两种方法

    问题:就是把从solr搜索出来的结果转成我们想要的实体类对象,很常用的情景. 1.使用@Field注解 @Field这个注解放到实体类的属性[字段]中,例如下面 public class User{ ...

  4. cnbolgs博客中添加Latex支持

    参考:http://www.cnblogs.com/ilogic/archive/2012/08/05/latex.html 主要是利用在线生成公式的工具:MathJax,但要在博客上获得 MathJ ...

  5. vue打包静态资源后显示空白及static文件路径报错

    1.打包之后打开dist的页面显示空白: 这个是打包项目比较常见的一个错误 改一下config下面的index.js中bulid模块导出的路径.因为打包后的index.html里边的内容都是通过scr ...

  6. Java基础笔试练习(六)

    1.在Java中,一个类可同时定义许多同名的方法,这些方法的形式参数个数.类型或顺序各不相同,传回的值也可以不相同.这种面向对象程序的特性称为? A.隐藏 B.覆盖 C.重载 D.Java不支持此特性 ...

  7. (二)Spring Boot 官网文档学习之入门

    文章目录 Spring Boot 是什么 系统要求 Servlet 容器 Maven方式安装Spring Boot 编写第一个 Spring Boot 项目 原文:https://docs.sprin ...

  8. python实战项目 — 爬取中国票房网年度电影信息并保存在csv

    import pandas as pd import requests from bs4 import BeautifulSoup import time def spider(url, header ...

  9. ES6语法基本使用

    什么是ES6? ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准,已经在2015年6月正式发布了.Mozilla公司将在这个标准的基础上,推出JavaScript 2. ...

  10. 监控SQL:通过SQL Server的DML触发器来监控哪些IP对表的数据进行了修改(2)

    原文:监控SQL:通过SQL Server的DML触发器来监控哪些IP对表的数据进行了修改(2) 在有些公司中,由于管理的不规范,或者是便于开发人员直接修改.部署程序,往往任何开发人员,都能登录到生产 ...