题目依然链接

题意:

  从根节点出发,每条边走两遍回到根节点,走边用时1,到达某个节点之后开始计时,到该节点最大的计时数时结束,回到根节点时根节点开始计时。求让所有计时都结束的最小时间。

Solve:

  很容易想到树形Dp,但是怎么Dp呢,因为记时开始后你还可以移动,所以并不是子树的简单累加,而是某种方法取max,我们先把状态定义下来,Dp[i]表示把以i为根的子树全部计时结束后需要的最小时间,那么我们要想一下怎么转移。

  如果我们已经知道了遍历顺序我们可以怎么转移,那就是Dp[i]=max(a[i],Dp[son1]+has1*2-1,Dp[son2]+has2*2-1+...+Dp[sonn]+hasn*n-1),hasj表示走到第j个儿子总共走的边数。

  为什么也是显而易见的,因为计时是同步的,所以我们只需取max就可以了。

  某大佬:我觉得有问题。

  我:一会儿为您解释。。。

  好的这个不太严谨的转移方程就写出来了,注意,是不太严谨的。

  那么我们怎么确定走儿子的顺序呢?这个再枚举就不太好了,我们要想一个好点的办法,这里其实很好想到要根据某个值进行排序,根据什么呢?其实这个只要稍微画画图就能想明白,如果Dp[i]+2*son[j]>Dp[j]+2*son[i].则i在j前面,这个怎么想到的呢,可以先画一下两个儿子的情况(这种很好证明)再类比一下,类别出结果再进行证明,怎么证明呢,这是我的证明方法:如果j在i前面,我们交换i和j的顺序至少不会更差(可以自己推推不等式,不难),所以我们可以直接让i在j前面,然后又有一个小小的问题,这样定义<会出问题吗,比如出现a>b且b<a或a>b且b>c且c>a,使sort函数死掉。其实并不会Dp[i]+2*son[j]>Dp[j]+2*son[i]就等价于Dp[i]-2*son[i]>Dp[j]-2*son[j]而Dp[i]-2*son[i]对于每个i是一个定值,所以并没有任何问题。

  好了顺序我们知道了,然后转移方程我们也知道了,但是刚才也有说到:转移方程不是很严谨(如下树,权值均为1),怎么让它严谨起来呢,很简单,感谢题目,让我们不用做任何改动就可以严谨起来(题目要求最后回来再计时根),想一想为什么。

  当然因为这个,我们也要做一些其他操作,这个各位应该都能想到解决方案。

  然后就是用不用开long long,多开当然没事,但是这一题不用开,不是数据水因为Dp最大也超不过n*2+max(a[i]),超不了int,但是多开一些没问题。

代码:

  

#include <cstdio>
#include <algorithm>
#include <string>
using namespace std;
const int maxn=+;
struct E{
int next;
int to;
E(){
next=to=;
}
}ed[maxn*];
int a[maxn];
int head[maxn];
int Dp[maxn];
int jl[maxn];
int er[maxn];
bool Cm(int a,int b){
return Dp[a]+er[b]*>Dp[b]+*er[a];//对什么进行排序想清楚
}
int Dfs(int x,int fa){
for(int i=head[x];i;i=ed[i].next){
if(ed[i].to==fa)
continue;
else{
Dfs(ed[i].to,x);
er[x]+=er[ed[i].to]+;
}
}
int js=;
for(int i=head[x];i;i=ed[i].next){//要先Dfs再记录,前面的题里有提到
if(ed[i].to==fa)
continue;
else{
js++;
jl[js]=ed[i].to;
}
}
if(!js){
Dp[x]=a[x];
return ;
}
sort(jl+,jl++js,Cm);
Dp[x]=a[x];
int has=;
for(int i=;i<=js;i++){
has++;
Dp[x]=max(Dp[jl[i]]+*has-,Dp[x]);
has+=er[jl[i]];
}
return er[x];
}
int tot;
void J(int a,int b){
tot++;
ed[tot].to=b;
ed[tot].next=head[a];
head[a]=tot;
}
int main(){
int n;
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%d",&a[i]);
int js1,js2;
for(int i=;i<=n-;i++){
scanf("%d%d",&js1,&js2);
J(js1,js2);
J(js2,js1);
}
int js=a[];//为保证最后再弄第一个的一些操作
a[]=;
Dfs(,);
printf("%d",max(js+*n-,Dp[]));
return ;
}

 

FarmCraft,又是Dp的更多相关文章

  1. BZOJ3829[Poi2014]FarmCraft——树形DP+贪心

    题目描述 In a village called Byteville, there are   houses connected with N-1 roads. For each pair of ho ...

  2. 【BZOJ3829】[Poi2014]FarmCraft 树形DP(贪心)

    [BZOJ3829][Poi2014]FarmCraft Description In a village called Byteville, there are   houses connected ...

  3. bzoj 3829: [Poi2014]FarmCraft 树形dp+贪心

    题意: $mhy$ 住在一棵有 $n$ 个点的树的 $1$ 号结点上,每个结点上都有一个妹子. $mhy$ 从自己家出发,去给每一个妹子都送一台电脑,每个妹子拿到电脑后就会开始安装 $zhx$ 牌杀毒 ...

  4. UVA 11137 Ingenuous Cubrency(dp)

    Ingenuous Cubrency 又是dp问题,我又想了2 30分钟,一点思路也没有,最后又是看的题解,哎,为什么我做dp的题这么烂啊! [题目链接]Ingenuous Cubrency [题目类 ...

  5. 动态规划——数位dp

    通过先前在<动态规划——背包问题>中关于动态规划的初探,我们其实可以看到,动态规划其实不是像凸包.扩展欧几里得等是具体的算法,而是一种在解决问题中决策的思想.在不同的题目中,我们都需要根据 ...

  6. [USACO 2012 Open Gold] Bookshelf【优化dp】

    传送门1:http://www.usaco.org/index.php?page=viewproblem2&cpid=138 传送门2:http://www.lydsy.com/JudgeOn ...

  7. CF Round #367 C题

    题目 链接:http://codeforces.com/contest/706/problem/C 好像又是DP... dp[i][0]表示第i个字符串不翻转成字典序排列的花费,dp[i][1]表示第 ...

  8. {POJ}{动态规划}{题目列表}

    动态规划与贪心相关: {HDU}{4739}{Zhuge Liang's Mines}{压缩DP} 题意:给定20个点坐标,求最多有多少个不相交(点也不相交)的正方形 思路:背包问题,求出所有的正方形 ...

  9. Lyk Love painting/convex hull/mumsic

    这场比赛真的是...打的好颓废啊... 所有题面的传送门 T1 分析: 我们发现 二分答案 + \(n^3\) \(dp\) 判断可行性 可以拿 60 分(于是就写好了啊!) 然后我们发现上面的 \( ...

随机推荐

  1. awardRotate转盘插件文字模糊问题和图片加载问题

    前言 最近在做一个转盘抽奖页面,使用了awardRotate.js发现字体和图片都有模糊,绘制的时候图片绘制不全,搜索一下之后发现针对awardRotate的解决方法比较少,针对canvas的比较多, ...

  2. 【JVM故事】一个Java字节码文件的诞生记

    万字长文,完全虚构. (一) 组里来了个实习生,李大胖面完之后,觉得水平一般,但还是留了下来,为什么呢?各自猜去吧. 李大胖也在心里开导自己,学生嘛,不能要求太高,只要肯上进,慢慢来.就称呼为小白吧. ...

  3. 4.vue class 绑定- model基础应用

        //代码可以复制自行体验   <template>     <div id="app" @click.stop="test('你点击了我big- ...

  4. 关于一个服务和api监控的界面,涉及ajax-jsonp,promise应用

    <!DOCTYPE html> <html class="mobile hairline" data-dpr=""> <head& ...

  5. 【转载】有人出天价买他的一个文案标题,今天10min教会你……

    目录 1. 套路 1:新闻社论 2. 套路 2:好友对话 3. 套路 3:实用锦囊 4. 套路 4:惊喜优惠 5. 套路 5:意外故事 本文由 简悦 SimpRead 转码, 原文地址 https:/ ...

  6. DockerFile构建镜像和Docker仓库

    利用commit理解镜像构成 注意: docker commit 命令除了学习之外,还有一些特殊的应用场合,比如被入侵后保存现 场等.但是,不要使用 docker commit 定制镜像,定制镜像应该 ...

  7. 使用matplotlib进行可视化

    转自:https://blog.csdn.net/qq_30614345/article/details/99049790 https://blog.csdn.net/qq_30614345/arti ...

  8. 阿里云用smtp无法发送邮件

    无法发送邮件是因为什么网络协议的要求必须要封掉25端口,而这个解封的话弄了很长时间也没有弄开,所以就换了别的方法 这个的话我这块用的是PHPMailer 然后我把这个PHPMailer的配置文件里的 ...

  9. JDBC——使用JDBC连接MySQL数据库

    在JDBC--什么是JDBC一文中我们已经介绍了JDBC的基本原理. 这篇文章我们聊聊如何使用JDBC连接MySQL数据库. 一.基本操作 首先我们需要一个数据库和一张表: CREATE DATABA ...

  10. Windwos安装Redis

    下载地址:https://github.com/MicrosoftArchive/redis 进入后点击release,下方可看到下载地址,下载mis文件,双击即可安装