hiho一下 第109周 Tower Defense Game 树DP+贪心

题目大意

给定一颗以1为根节点的树,每个节点有一个购入价格p和卖出价格q

进入一个节点时需要花费p,离开时可以收回q,每个节点只产生一次购入和卖出。

请你选择一个遍历的顺序,要求在遍历的过程中身上的钱数不小于0,且出发时带的钱数最少。

按照遍历的顺序是指:当你选择了一颗子树之后,你需要将这个子树全部走完,才能选择其他子树

 

.....................................

简化到二叉树的情况考虑,

根节点A的左右儿子分别为B和C,

如果最后停留在B,则开始带的最多钱为 min(  MAX(p1,p1-q1+p2-q2+p3),max(p1,p1-q1+p3-q3+p2) )

显然根据p>=q

答案就是min(p1-q1+p2-q2+p3,p1-q1+p3-q3+p2);

因此可以看到,比较的是 psum-(qsum-qx)  x为最后停留的一边

因此对于二叉树的情况,我们应该从qi先选大后选小

同理可以推广到多叉树的情况,还是按qi从大到小选.

 

刚才从多个儿子里面按顺序选的 条件是:qi先选大后选小

此时若儿子代表是一棵树的话,pi和qi的意思就应该变成了,选这棵树 所需要的最大初始钱,和返回时会剩余的钱。

这个并不是简单的把子树所有节点的p和q相加,

 

 

 

需要递归的过程中先算出每个子树的pt_i和pt_i才可以。 

 

#include 
using namespace std;
typedef long long ll;
const int mod=1e9+7;
const int N=13240;
vectormp[N];
ll p[N],q[N];
bool cmp(int a,int b)
{
    return q[a]>q[b];   //按照qi排序
}
ll get(int x,int fa)
{
    for(int i=0; i


 

 

 

你可能感兴趣的:(动态规划,树dp,hihocoder,贪心,玄学の贪心)