[bzoj4899]记忆的轮廓 题解(毒瘤概率dp)
题目背景
四次死亡轮回后,昴终于到达了贤者之塔,当代贤者夏乌拉一见到昴就上前抱住了昴“师傅!你终于回来了!你有着和师傅一样的魔女的余香,肯定是师傅”。
众所周知,大贤者是嫉妒魔女沙提拉的老公,400年前与神龙、剑圣一起封印魔女因子暴走的莎缇拉。在魔女茶会的时候,莎缇拉也表示过对昴浓浓的爱意,昴便是被莎缇拉召唤来异世界的。
而贤者之塔中的资料与试炼,似乎都指向同一种可能性……记忆的轮廓,逐渐显形……
题目描述
通往贤者之塔的路上,有许多的危机。
我们可以把这个地形看做是一颗树,根节点编号为1,目标节点编号为n,其中1-n的简单路径上,编号依次递增,在[1,n]中,一共有n个节点。
我们把编号在[1,n]的叫做正确节点,[n+1,m]的叫做错误节点。一个叶子,如果是正确节点则为正确叶子,否则称为错误叶子。
莎缇拉要帮助昴到达贤者之塔,因此现在面临着存档位置设定的问题。为了让昴成长为英雄,因此一共只有p次存档的机会,其中1和n必须存档。被莎缇拉设置为要存档的节点称为存档位置。
当然不能让昴陷入死循环,所以存档只能在正确节点上进行,而且同一个节点不能存多次档。因为通往贤者之塔的路上有影响的瘴气,因此莎缇拉假设昴每次位于树上一个节点时,都会等概率选择一个儿子走下去。每当走到一个错误叶子时,再走一步就会读档。
具体的,每次昴到达一个新的存档位置,存档点便会更新为这个位置(假如现在的存档点是i,现在走到了一个存档位置j>i,那么存档点便会更新为j)。读档的意思就是回到当前存档点。
初始昴位于1,当昴走到正确叶子n时,便结束了路程。莎缇拉想知道,最优情况下,昴结束路程的期望步数是多少?
输入格式
第一行一个正整数T表示数据组数。
接下来每组数据,首先读入三个正整数n,m,p。
接下来m-n行,描述树上所有的非正确边(正确边即连接两个正确节点的边),用两个正整数j,k表示j与k之间有一条连边,j和k可以均为错误节点,也可以一个为正确节点另一个为错误节点。数据保证j是k的父亲。
输出格式
T行每行一个实数表示每组数据的答案。请保留四位小数。
样例输入
1
3 7 2
1 4
2 5
3 6
3 7
样例输出
9.000
数据范围及约定
50%,n=p
70%,50<=p<=n<=500
100%,50<=p<=n<=700,m<=1500,T<=5
数据保证每个除了n的正确节点均有至少2个儿子,至多3个儿子。
要是考试的时候题面上有50%n=p就先写这个了
首先考虑n=p的做法:
设g[i]表示对于一个错误节点i,期望走多少步会读档
则$g[i]=\frac{1}{du[i]\cdot{\sum_{(j为i的儿子 )} { g[j]}}}+1$
另外预处理
$sum[i]=\sum{g[j]}$,j为i的错误儿子
那么对于正确节点i走到n的期望步数f[i],有
$f[i]=du[i]+f[i+1]+sum[i]$
之后是对于普遍情况,比较暴力的转移做法
设f[i,j]表示当前存档点为i,还剩j次存档机会。
我们需要预处理一个step[i,j],表示存档点为i,从i开始走到正确节点j的期望步数(中间不能存档)
那么显然有
$step[i][i]=0$
$step[i][j]=step[i][j-1]*du[j-1]+du[j-1]+sum[j-1]\ (i<j)$
预处理step的时间为n2
之后枚举存档点转移即可
复杂度O(n2p)
最后的正解
被博主鸽了hhh
“咦但是你A了这道题啊?”
呃是这样的
出题人最终给了三种正解
博主选择的是第二种
但是并不会证明它的正确性(因为真的很像qj测试点?)
其实就是设定一个距离,只在距离内转移dp数组
事实上,我觉得出题人在解释这种做法时给出的解释也很含糊
好像只是说了为什么step数组爆炸增长不会影响大局,没有给出指定距离内转移的合理性
所以大家还是直接点上面的链接看出题人讲解好了
博主有时间的话也会尝试使用另外两种做法A掉这道题的
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>'')
{if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<='')
{x=(x<<)+(x<<)+ch-'';ch=getchar();}
return x*f;
}
const int N=,dis=;
int n,m,p,T;
int du[N],nxt[N],to[N],head[N],tot=;
double g[N],dp[N][N],step[N][N],sum[N];
bool v[N];
void add(int x,int y)
{
to[++tot]=y;
nxt[tot]=head[x];
head[x]=tot;
du[x]++;
}
void dfs(int x)
{
v[x]=;g[x]=;
for(int i=head[x];i;i=nxt[i])
{
dfs(to[i]);
g[x]+=(double)/du[x]*g[to[i]];
}
}
void work()
{
n=read();m=read();p=read();
for(int i=;i<=m;i++)
head[i]=to[i]=nxt[i]=du[i]=v[i]=sum[i]=;
tot=;
for(int i=;i<=m-n;i++)
{
int x=read(),y=read();
add(x,y);
}
for(int i=;i<n;i++)du[i]++;
for(int i=n+;i<=m;i++)
if(!v[i])dfs(i);
for(int i=;i<=n;i++)
for(int j=head[i];j;j=nxt[j])
sum[i]+=g[to[j]];
//for(int i=1;i<=n;i++)printf("%lf\n",sum[i]);
for(int i=;i<=n;i++)
{
step[i][i]=;
for(int j=i+;j<=n;j++)
step[i][j]=(double)du[j-]*step[i][j-]+sum[j-]+du[j-];
}
memset(dp,,sizeof(dp));
dp[n][]=;
for(int j=;j<=p;j++)
for(int i=;i<=n;i++)
for(int k=i+;k<=n&&k-i<=dis;k++)
dp[i][j]=min(dp[i][j],dp[k][j-]+step[i][k]);
printf("%.4lf\n",dp[][p]);
}
int main()
{
T=read();
while(T--)work();
return ;
}
[bzoj4899]记忆的轮廓 题解(毒瘤概率dp)的更多相关文章
- bzoj 4899 记忆的轮廓 题解(概率dp+决策单调性优化)
题目背景 四次死亡轮回后,昴终于到达了贤者之塔,当代贤者夏乌拉一见到昴就上前抱住了昴“师傅!你终于回来了!你有着和师傅一样的魔女的余香,肯定是师傅”.众所周知,大贤者是嫉妒魔女沙提拉的老公,400年前 ...
- [BZOJ4899]:记忆的轮廓(概率DP)
题目传送门 题目描述: 通往贤者之塔的路上,有许多的危机. 我们可以把这个地形看做是一颗树,根节点编号为1,目标节点编号为n,其中1-n的简单路径上,编号依次递增, 在[1,n]中,一共有n个节点.我 ...
- 记忆的轮廓 期望 四边形不等式dp|题解
记忆的轮廓 题目描述 通往贤者之塔的路上,有许多的危机.我们可以把这个地形看做是一颗树,根节点编号为1,目标节点编号为n,其中1-n的简单路径上,编号依次递增,在[1,n]中,一共有n个节点.我们把编 ...
- Bzoj4899 记忆的轮廓
B. 记忆的轮廓 题目描述 通往贤者之塔的路上,有许多的危机.我们可以把这个地形看做是一颗树,根节点编号为1,目标节点编号为n,其中1-n的简单路径上,编号依次递增,在[1,n]中,一共有n个节点.我 ...
- BZOJ4899: 记忆的轮廓【概率期望DP】【决策单调性优化DP】
Description 通往贤者之塔的路上,有许多的危机. 我们可以把这个地形看做是一颗树,根节点编号为1,目标节点编号为n,其中1-n的简单路径上,编号依次递增, 在[1,n]中,一共有n个节点.我 ...
- BZOJ4899 记忆的轮廓(概率期望+动态规划+决策单调性)
容易发现跟树没什么关系,可以预处理出每个点若走向分叉点期望走多少步才能回到上个存档点,就变为链上问题了.考虑dp,显然有f[i][j]表示在i~n中设置了j个存档点,其中i设置存档点的最优期望步数.转 ...
- Codeforces 258D Little Elephant and Broken Sorting (看题解) 概率dp
Little Elephant and Broken Sorting 怎么感觉这个状态好难想到啊.. dp[ i ][ j ]表示第 i 个数字比第 j 个数字大的概率.转移好像比较显然. #incl ...
- loj6171/bzoj4899 记忆的轮廊(期望dp+优化)
题目: https://loj.ac/problem/6171 分析: 设dp[i][j]表示从第i个点出发(正确节点),还可以有j个存档点(在i点使用一个存档机会),走到终点n的期望步数 那么 a[ ...
- HDU 5781 ATM Mechine (概率DP)
ATM Mechine 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5781 Description Alice is going to take ...
随机推荐
- lightoj1200 【完全背包】
题意: 有一个能放W重的袋子,然后妻子给了老公一列清单,每个item会有价格,数量,重量. 首先得满足老婆的要求,然后在可装的地方输出最大还能拿多少使得拿的东西的钱最多. 注意标题是thief,我想大 ...
- bzoj 1176 [Balkan2007]Mokia 【CDQ分治】
W过大,很难在线维护,考虑离线算法 给每个操作加一个时间属性n,显然,对于n=i的询问,对它有影响的修改只在n<i中,所以可以CDQ(因为是按时间序读进来的,所以不用排序了 对于统计矩形和,可以 ...
- IT兄弟连 JavaWeb教程 Servlet线程安全问题
在Internet中,一个Web应用可能被来自西面八方的客户并发访问(即同时访问),而且有可能这些客户并发访问的是Web应用中的同一个Servlet,Servlet容器为了保证能同时相应多个客户端要求 ...
- SQL_MODE 的设置
查看当前的 SQL_MODE SELECT @@sql_mode SELECT @@sql_mode 的执行结果 mysql> SELECT @@sql_mode; +------------- ...
- 如何在VS2010的VC++ 基于对话框的MFC程序中添加菜单
方法1:亲测 成功 转载自https://social.msdn.microsoft.com/Forums/vstudio/zh-CN/48338f6b-e5d9-4c0c-8b17-05ca3ef ...
- Codeforces Round #418 (Div. 2) B
Description Sengoku still remembers the mysterious "colourful meteoroids" she discovered w ...
- Subsequence HDU - 3530
Subsequence HDU - 3530 方法:单调队列区间最大最小 错误记录(本地写错)的原因:写成每次试着扩展右端点,却难以正确地处理"在多扩展右端点之后减去多扩展的部分" ...
- set+线段树 Codeforces Round #305 (Div. 2) D. Mike and Feet
题目传送门 /* 题意:对于长度为x的子序列,每个序列存放为最小值,输出长度为x的子序列的最大值 set+线段树:线段树每个结点存放长度为rt的最大值,更新:先升序排序,逐个添加到set中 查找左右相 ...
- 在eclipse中配置Tomcat并将项目部署到Tomcat上
参考:http://blog.csdn.net/yerenyuan_pku/article/details/51830104 首先在点击window窗口然后preferences 然后点击Add,选择 ...
- window上安装MySQL
一.安装MySQL 1.1 下载解压缩版的安装包,解压,然后配置环境变量 PATH=.......;D:\Program Files (x86)\mysql-5.5.27-win32\bin (注意是 ...