思路

题意:有一只蜗牛爬上树睡着之后从树上掉下来,发现后面的"房子"却丢在了树上面, 现在这 只蜗牛要求寻找它的房子,它又得从树根开始爬起,现在要求一条路径使得其找到房子 所要爬行的期望距离最小. 爬行距离如下计算, 题目规定每一个分支和枝末都看做是 一个节点, 这些节点之间的距离都是1, 在分支上可能会有热心的毛毛虫, 这些毛毛虫 会如实的告诉蜗牛他之前是否经过这条路径, 也正是因为毛毛虫, 因此询问毛毛虫的顺 序使得这题的期望是不同的. 输入数据时给定的一个邻接关系,通过上一个节点来构图 同时字符 'Y'表示该点有毛毛虫, 字符'N'表示该点

解法:dp[i][0]表示以该点为根的节点找不到房子时要爬行最少的距离, 这个值有什么用呢?
这个值就是用去计算房子落在其他叶子节点时,其对爬行距离的负面效应有多大.
dp[i][1]表示以该点为根的节点在选择好所有分支点的爬行方案后,枚举完房子落在该
子树所有叶子节点上的总爬行距离的最小值,这是一个值告诉我们这棵子树对爬行距离
的正面效应有多大.那么有动态方程: ch[x]表示x节点一共有多少个孩子节点

 dp[i][0] = sum{ dp[j][0] + 2 } 当i没有毛毛虫且要求j是i的孩子节点,这个是很好理解的, 多出来的2就是连接该孩子节点的边来回的两次 dp[i][0] = 0 当该点有毛毛虫的时候, 原因是因为毛毛虫会告诉我们这点下面没有房子当一个节点时叶子节点的时候,那么 dp[i][0] = dp[i][1] = 0; 要明确dp[i][1]是表示在遇到分支选择的先后顺序决定后,我们枚举房子在其各个叶子上的所要爬行的总距离dp[i][1] = sum{ (sum{dp[1..j-1][0]+2}+1}*ch[j] +  dp[j][1]}, 其中j是i的孩子 这个方程要怎么去理解呢? 意思翻译过来就是遍历i的孩子中的j号子树所有叶子节点所要爬行的最短距离.其值就是: 前面[1, j-1]号子树没有找到节点所爬行的最短距离加上走了的多余的边再加上遍历j号子树所有叶子节点所爬行的最短距离, 那么这里显然谁前谁后就会决定最后值的大小现在只考虑序列中任意两棵子树A,B, 如果A放前面的话, 枚举完所有房子所在位置后的总距离就是ans1 = (ch[A] + dp[A][1]) + ((dp[A][0]+2)*ch[B] + dp[B][1] + ch[B])前一个括号是假设枚举房子落在A的所有叶子上, 后面的扩后是枚举在B的所有叶子上 ans2 = (ch[B] + dp[B][1]) + ((dp[B][0]+2)*ch[A] + dp[A][1] + ch[A])ans1 - ans2 = (dp[A][0]+2)*ch[B] - (dp[B][0]+2)*ch[A]

名义上是期望值,而实际上就是找一条路径。什么路径呢?从根节点走遍所有的叶子节点所花费步数最短的路径。

明确了题意后该怎么做呢?

首先看我们需要什么?

目前有个根节点,我们需要知道从他向一个分支走,失败步数是多少,成功步数是多少?

那么怎么维护我们需要的东西呢?

首先我们先给他们起个名:suc,fai;

其次再给一个节点的叶子节点的个数起个名:son

起名完事之后我们就要更新了。

先谈叶子节点,显然叶子节点的suc[x]=0,fai[x]=0,son[x]=1;

之后就是向上更新了,son和fai也很好搞

对于son的更新son[fa]+=son[x];

对于fai的更新fai[fa]+=fai[x]+2(此时worm[x]=0);否则的话不用管。

对于最不好弄的suc更新:

首先对于我们当前讨论的要走的子节点pn,这时候,蜗牛已经经过了走p1~pn-1的失败的步数,所以这些失败的步数是要记录的,我们给它命名为cnt-fai,此时我们会多走几个cnt-fai呢?我们发现,一共会多走son[pn]个cnt-fai,然而每次走过一个叶子节点后,更新一次suc[x],然后再将其视为失败,返回,找下一个叶子节点,此时我们就会发现,再返回到px的时候,这个蜗牛还需要继续返回一层,即返回到目前的根节点x,多走出一步,多走多少个一步呢?仍然是son[pn]个,用公式来写就是这样:suc[x]+=(cntfai+1)∗son[pn]+suc[pn]suc[x]+=(cntfai+1)∗son[pn]+suc[pn]suc[x]+=(cntfai+1)*son[pn]+suc[pn]

同时更新cntfai,cntfai+=fai[pn]+2cntfai+=fai[pn]+2cntfai+=fai[pn]+2这个2就是指去以及回来的两步

以上,dp的部分差不多搞定了,观察上面的式子发现,唯一不能确定的就是pn是什么鬼?

也就是说,对于一个根节点x我们按照什么顺序来讨论他的子节点会使得x的suc最小呢?

以下引用discuss里某神犇的证明

假设交换相邻的两颗子树的选择顺序,设P1,P2为选他们的概率,A1,A2为房子确实在上面所需的步数,B1,B2为实际上不在上面所需的步数,则
调整后:Delta=P1A1+P2(B1+A2)-P2A2-P1(B2+A1)=P2B1-P1B2
于是Delta<0 <=> B1/P1小于B2/P2
而题设情况即为Delta<0
于是应按照B/L排序 即遍历此子树所需步数/其所含叶子树

转化为公式呢?就是这个东西

(fai[u]+2)∗son[v]<(fai[v]+2)∗sonu∗son[v]<(fai[v]+2)∗sonu*son[v]<(fai[v]+2)*son[u]

其中u和v分别是两个子节点。

后记:这题是道好题,做完后能学到不少东西,值得一做,然而自己在做的时候对于这种双线的把握还不是很好,比较欠缺,什么鬼的排序根本没想到,自己对于这种难题的把握还是差很多啊!


作者:wzq_QwQ
来源:CSDN
原文:https://blog.csdn.net/wzq_QwQ/article/details/46359905?utm_source=copy
版权声明:本文为博主原创文章,转载请附上博文链接!

我的理解

:树形dp的思路,求出走每颗子树的最小步数。因为对于每颗子树,要么在这里找到壳,要么没有找到壳,所以设置dp[i][0]表示从i开始,遍历完所有子树,不能找到壳的最少步数,dp[i][1]表示,在最优策略下找到壳的最少步数(这和我们普通的dp不同,他是由两个最优子结构决定的,我们设的dp转移是一个最优子结构,而dp[i][1]表示的最优策略也是一个最优子结构。我们发现其实在最优策略下找到壳是可以贪心的,因为必然是朝失败次数少的方向转移)。 对于这样的双线最优子结构问题,常见的思路都是通过贪心来优化掉其中一线,否则复杂度会爆。就这题来说,如果不贪心优化的话,对于dp[i][1]就需要状压来求(二进制枚举顺序).

代码

#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <string.h>
#include <math.h>
using namespace std;
const int maxn=1e3+8;
typedef long long ll;
struct Edge
{int u,v,w,next;
}edge[maxn];
int num,n;
int head[maxn];
int dp[maxn][2];
int vis[maxn];
int ch[maxn];
void addEdge(int u,int v,int w)
{edge[num].u=u;edge[num].v=v;edge[num].w=w;edge[num].next=head[u];head[u]=num++;
}
void init()
{memset(head,-1,sizeof(head));memset(dp,0,sizeof(dp));memset(ch,0,sizeof(ch));memset(vis,0,sizeof(vis));num=0;
}
bool cmp(int a,int b)
{return (dp[a][0]+2)*ch[b]<(dp[b][0]+2)*ch[a];
}
int dfs(int x)
{if(head[x]==-1){dp[x][0]=dp[x][1]=0;return ch[x]=1;}vector<int> g;for(int i=head[x];i!=-1;i=edge[i].next){int v=edge[i].v;ch[x]+=dfs(v);g.push_back(v);}sort(g.begin(),g.end(),cmp);for(int i=0;i<g.size();i++){dp[x][1]+=dp[x][0]*ch[g[i]]+dp[g[i]][1]+ch[g[i]];//前面失败的+g[i]次成功的dp[x][0]+=dp[g[i]][0]+2;//找不到必然是子树找不到+来回两次跑}if(vis[x]) dp[x][0]=0;return ch[x];
}
int main(int argc, char const *argv[])
{while(scanf("%d",&n)!=EOF&&n){char s[5];int p;scanf("%d %s",&p,s);init();for(int i=2;i<=n;i++){scanf("%d %s",&p,s);vis[i]=(s[0]=='Y');addEdge(p,i,0);}dfs(1);printf("%.4f\n",1.0*dp[1][1]/ch[1]);}return 0;
}

The Lost House POJ - 2057(树形dp+贪心 (双线最优子结构问题))相关推荐

  1. poj 2057 树形DP,数学期望

    题目链接:http://poj.org/problem?id=2057 题意:有一只蜗牛爬上树睡着之后从树上掉下来,发现后面的"房子"却丢在了树上面, 现在这只蜗牛要求寻找它的房子 ...

  2. Fire (poj 2152 树形dp)

    Fire (poj 2152 树形dp) 给定一棵n个结点的树(1<n<=1000).现在要选择某些点,使得整棵树都被覆盖到.当选择第i个点的时候,可以覆盖和它距离在d[i]之内的结点,同 ...

  3. CodeForces - 1453E Dog Snacks(树形dp+贪心)

    题目链接:点击查看 题目大意:给出一棵有根树,现在需要选择一个最小的 k 值,可以满足下列的 n 次操作: 起始时位于点 1(根节点) 每一步选择一个未被遍历的节点中,距离最近的,且必须满足此距离小于 ...

  4. 2020CCPC(秦皇岛) - Kingdom‘s Power(树形dp+贪心)

    题目大意:给出一棵 n 个节点的有根树,点 1 为根节点,现在在根节点有无穷多个士兵,每一秒可以控制任意一个士兵向任意一个单位移动一步,士兵移动到的点会被永久占领,现在问最少需要经过多少秒,才能将所有 ...

  5. A. Parsa‘s Humongous Tree(树形DP + 贪心)

    Problem - 1528A - Codeforces 两个玩家正在玩一个游戏.他们有一个整数1,2,...,n的排列组合(排列组合是一个数组,其中从1到n的每个元素正好出现一次).这个排列组合没有 ...

  6. [Codeforces 814D] An overnight dance in discotheque 树形dp,贪心

    题目链接 题解:这道题,首先可以发现,圆与圆关系只有内含与外离, 所以可以建立出一个树形结构, 每个圆的父亲是与这个圆半径相差最小且包含这个圆的圆, 这样,整个一张图形成了一个森林,可以将圆按半径排序 ...

  7. POJ 3342 树形DP+Hash

    这是很久很久以前做的一道题,可惜当时WA了一页以后放弃了. 今天我又重新捡了起来.(哈哈1A了) 题意: 没有上司的舞会+判重 思路: hash一下+树形DP 题目中给的人名hash到数字,再进行运算 ...

  8. poj 2342 树形DP

    树形DP入门题目. 树形DP说白了就是在搜索的时候动态规划. 只要你懂的深搜+动态规划,就能理解这个基础题了. 先直接搜索到最底层,然后一层一层动态规划,可以说有点像数塔. dp[i][1],dp[i ...

  9. poj 2486 树形dp

    思路:这题是裸的树形dp.dp[i][j]表示第i个节点花费j步并且从子节点返回,能得到的最大苹果数:nback[i[j]表示第i个节点花费j步并且进入某个子节点不返回,能得到的最大苹果数.那么我们就 ...

最新文章

  1. 智能工厂4.0:数字世界和物理世界的融合【附下载】
  2. 修改RHEL7/centos7网卡为eth0
  3. 从宝马与京东携手,透视汽车后市场变革
  4. ASP.NET中的AdRotator控件即广告控件的使用
  5. 01_NumPy介绍,什么是NumPy,Python应用、(NumPy、SciPy、Matplotlib相关网址)--来自菜鸟和NumPy中文网
  6. jquery实现增删改(伪)-老男孩作业day13
  7. LeetCode 9. 回文数
  8. matlab meshgrid函数_matlab入门(三)图像可视化
  9. html 页面缩放事件,浏览器缩放不触发window.onresize事件的BUG
  10. 将自己的姿态放低:你应具备赚钱以外的四种能力
  11. gif生成工具(免费)
  12. 和利时dcs系统服务器设置,和利时DCS系统常见问题分析
  13. 微信小程序 列表item点击事件
  14. 墓碑上的字符c语言程序设计,刻在死者墓碑上.概述人物事迹.赞美人物品格的文字叫墓志铭.信客离开我们后.村民为他树碑.请你为其撰写墓志铭. 题目和参考答案——青夏教育精英家教网——...
  15. 肯德尔系数怎么分析_肯德尔和谐系数
  16. 应作如是观--全息的宇宙
  17. 极客创新大赛|微创机器人号探索飞船即将启航
  18. Laya.TextInput组件中禁用后改变输入框背景色和文字颜色
  19. 计算机格式化什么意思,u盘格式化是什么意思,教您u盘格式化是什么意思
  20. java对比俩个word文件内容差异

热门文章

  1. SuperMap GIS地质体数据处理QA
  2. java的jar文件
  3. bzoj1605 洛谷2905 [Usaco2008 Open]Crisis on the Farm 牧场危机(DP)
  4. 选择城市,按城市的首字母进行排序
  5. 客户旅程_编程如何找到我的:21岁开发人员的7年旅程
  6. pci总线定时协议_PCI总线标准及协议
  7. 【吾日三省吾身】2015.5.19-慎独、慎言、慎行、戒骄、戒躁、戒怒
  8. 如何在eclipse制作的APP中添加背景图
  9. 华为数据之道(3):面向业务的信息架构建设
  10. 如何清理windows server 2008 R2 中winsxs文件夹