(当时写这篇题解的时候,,,不知道为什么,,,写的非常冗杂,,,不想改了。。。)

题意:一张有n个点的图,其中每天第i个点到第j个点的边都有$P_{i, j}$的概率开放,每天可以选择走一步或者留在原地,求从1号点到n号点的最优期望值。
题解:
  $f(x)$表示从$x$出发,走到$n$的最优期望时间。因为在一个点x时,如果要选择后继节点,肯定要选$f$值越小的越好,因此考虑贪心的选择后继状态。$a_{i}$表示$f(x)$第$i$小的x。考虑分层DP,依次确定$a_{i}$的值,并同时维护$f$值。
  假设我们现在枚举到了第$i$层,那么对于任意一点$x$,只在$a_{1}...a_{i - 1} + x$里面选择后继状态,因为只有这样才能保证期望不变得更劣(如果要选择其他点作为后继的话,可以看做等到了那个点已经被加入$a$集合中再考虑作为后继,如果那个点加入$a$集合的时间还要比$x$慢,那肯定去那个点是会使得期望变大的,还不如不去)
  注意到如果一个点$x$已经被放入$a$集合,那么肯定不需要再更新它了,因为它的值已经求出来并且固定了。(其实感觉思路有点类似于dijkstra,都是用已经找到最短路的点来更新其他点,每多找到一个点的最优解,下次就多用这个点来更新其他点)
  对于第$i$层的最优点$a_{i}$,我们有:
  $$f(a_{i}) = 1 + \sum_{j = 1}^{i}(f(a_{j}) P_{a_{i}, a_{j}} \prod_{k = 1}^{j - 1}(1 - P_{a_{i},a_{k}}))$$
  当然这个式子对于其他点$x$也是成立的,只需要把所有的$a_{i}$都替换成$x$即可,注意要把$j == i$时的$a_{j}$也替换掉。于是替换完后再移下项,把$f(x)$都移到左边,式子就变为了:
  $$[1 - \prod_{k = 1}^{i - 1}(1 - P_{a_{i}, a_{k}})] f(x) = 1 + \sum_{j = 1}^{i - 1}(f(a_{j}) P_{x, a_{j}} \prod_{k = 1}^{j - 1}(1 - P_{x, a_{k}}))$$
  应该还是比较好理解的,因为只会选择$a$集合中的点,且在$a$数列中越靠前的越好,因此要优先考虑选靠前的$a_{j}$,对于一个$a_{j}$,只有$a_{1} ... a_{j - 1}$都走不到的时候才会选择它,因此它的贡献就是可以到它的概率*之前的点都不能到的概率。
  如果所有$a$集合中的点都到不了,我们还有保底的选项——留在原地,这个选择体现在第一个式子中的求和符号的上界为$a_{i}$自己,而在第二个式子中,这一部分已经被移项到了左侧。
  因此我们只需要按层DP,在每层内,选择$f$值最小的那个作为新点加入$a$集合,不断更新维护其他未确定点的$f$即可。、
  
  那么我们考虑怎么来实现这个东西。。。(实现细节)
  观察到式子中,$i$是从小到大枚举的,也就是说对于相邻的两层$i - 1, i$中的同一个点$x$,它们的$f(x)$所相差的仅仅只有式子中随着$i$增大而多出来的那部分。因此我们可以每次只算出增量,然后每次都与前面的累加,得到新的$f$值,这样就可以快速的算出$f$值。
  但是如果我们直接求$f$值,也就是把左边那坨系数除到右边去的话,就不太好累加,因此我们考虑将右边和左边分别储存,用$f$数组来存右边的值,$g$来存左边的系数,这样如果我们需要用到$f$的值,直接用$g$和$f$凑出真正的$f$值即可。
  但是考虑到等式右边有一个部分和等式左边是一样的:$\prod_{k = 1}^{j - 1}(1 - P_{x, a_{k}})$,因此如果我们令$g$表示这个,而不是左边那一整坨的话,就可以快速的得到左边需要的值。这样的话,要表示真正的$f$值只需要用$f$去除$(1 - g)$即可。
  方便起见,如果一个点$pos$即将被加入$a$集合,我们就把这个点真实的$f$值计算出来,以供后面的点使用。
  观察到对于每一层的$f$值,我们实际上只用到了$1...i - 1$层的值,因此我们在循环的开头就已经可以计算出$f$的大小了,所以我们只需要在循环的开头就把当前层要加入$a$集合的那个点,也就是把$f$值最小的那个点加入集合。
  然后再对于所有没有被加入$a$集合的点,处理下一层所需要的$f$值即可。
  因为下一次的$i - 1$相当于现在的$i$,而加入现在的$i$时,所需要用到的$g$值还停留在现在的$i - 1$,所以要先更新$f$,再更新$g$.
  更具体的来说,就是:
  对于$f(x)$,每次新增$f(a_{i})P_{x, a_{i}} \prod_{k = 1}^{i - 1}(1 - P_{x, a_{k}}) = f(a_{i})P_{x, a_{i}}g(x)$.
  对于$g(x)$,每次新乘$(1 - P_{x, a_{i}})$

 #include<bits/stdc++.h>
using namespace std;
#define R register int
#define AC 1100
#define db double int n, p[AC][AC];
double f[AC], g[AC];
bool z[AC]; inline int read()
{
int x = ;char c = getchar();
while(c > '' || c < '') c = getchar();
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x;
} void pre()
{
n = read();
for(R i = ; i <= n; i ++)
for(R j = ; j <= n; j ++) p[i][j] = read();
for(R i = ; i < n; i ++) f[i] = g[i] = ;//f[n], g[n] = 0
} void work()
{
for(R i = ; i <= n; i ++)//枚举层数
{//因为已经存下了前缀和,所以就不需要存a_i了
double maxn = 1e18; int pos = ;
for(R j = ; j <= n; j ++)
if(!z[j] && g[j] < && f[j] / ( - g[j]) < maxn)
maxn = f[j] / ( - g[j]), pos = j;
if(!pos) break;//因为pos的f已经被确定下来了,所以这时就可以把(1 - g[pos])除过去了
z[pos] = , f[pos] /= ( - g[pos]);
for(R j = ; j <= n; j ++)
if(!z[j])
{
f[j] += g[j] * f[pos] * ((db) p[j][pos] / );
g[j] *= (db) ( - p[j][pos]) / ;
}
}
printf("%.10lf", f[]);
} int main()
{
// freopen("in.in", "r", stdin);
pre();
work();
// fclose(stdin);
return ;
}

CF605E Intergalaxy Trips 贪心 概率期望的更多相关文章

  1. CF605E Intergalaxy Trips

    CF605E Intergalaxy Trips 考虑你是不知道后来的边的出现情况的,所以可以这样做:每天你都选择一些点进行观察,知道某天往这些点里面的某条边可用了,你就往这条边走.这样贪心总是对的. ...

  2. CF623D birthday 贪心 概率期望

    题意:n个人,玩抓人游戏,每抓住一个人都要猜这个人是谁.对于每一局,第i个人有$p_{i}$的概率被抓到.游戏结束当且仅当每个人都在某局中被抓到并且猜中自己的名字,求一个合适的策略来使得期望游戏局数最 ...

  3. luoguP3232 [HNOI2013]游走 贪心 + 概率期望 + 高斯消元

    首先,题目中的无向简单连通图代表着没有自环,重边... 总分的期望 = 每条边的期望之和...................每条边的期望又可以拆成$u \to v$的期望和$v \to u$的期望 ...

  4. Intergalaxy Trips CodeForces - 605E (期望,dijkstra)

    大意: 给定矩阵$p$, $p_{i,j}$表示每一秒点$i$到点$j$有一条边的概率, 每秒钟可以走一条边, 或者停留在原地, 求最优决策下从$1$到$n$的期望用时. $f_x$为从$x$到$n$ ...

  5. Codeforces 912D Fishs ( 贪心 && 概率期望 && 优先队列 )

    题意 : 给出一个 N * M 的网格,然后给你 K 条鱼给你放置,现有规格为 r * r 的渔网,问你如果渔网随意放置去捕捞小鱼的情况下,捕到的最大期望值是多少? 分析 :  有一个很直观的想法就是 ...

  6. 【CF605E】Intergalaxy Trips(贪心,动态规划)

    [CF605E]Intergalaxy Trips(贪心,动态规划) 题面 Codeforces 洛谷 有\(n\)个点,每个时刻第\(i\)个点和第\(j\)个点之间有\(p_{ij}\)的概率存在 ...

  7. CF#335 Intergalaxy Trips

     Intergalaxy Trips time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  8. CodeForces 605 E. Intergalaxy Trips

    E. Intergalaxy Trips time limit per test:2 seconds memory limit per test:256 megabytes input:standar ...

  9. 【BZOJ3143】【HNOI2013】游走 && 【BZOJ3270】博物馆 【高斯消元+概率期望】

    刚学完 高斯消元,我们来做几道题吧! T1:[BZOJ3143][HNOI2013]游走 Description 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小 ...

随机推荐

  1. PHP 0817PHP 0817 (PHP, Exploit) writeup

    作为一只ctf小白,这个题看到之后真是丝毫没有思路.虽然能基本理解php,但还是没能顺利答出,最后直接进行了搜索. 虽然做技术,“固执”是优点.但是出于对自身自身情况的了解,我觉得现阶段看题解还是很有 ...

  2. LUA对象

    Rectangle = {width = , height = , area = }; function Rectangle:new(o, width, height) o = o or {}; se ...

  3. 搜索引擎ElasticSearch系列(四): ElasticSearch2.4.4 sql插件安装

    一:ElasticSearch sql插件简介 With this plugin you can query elasticsearch using familiar SQL syntax. You ...

  4. Windows隐藏账户

    win7系统用户由于共享文件,会开启Guest来宾帐户,开启Guest来宾帐户后发现登录界面会显示guest帐户,但是只有在有密码的情况下才会显示,很多用户不喜欢显示guest帐户,那么Win7登录界 ...

  5. Python接口测试实战3(上)- Python操作数据库

    如有任何学习问题,可以添加作者微信:lockingfree 课程目录 Python接口测试实战1(上)- 接口测试理论 Python接口测试实战1(下)- 接口测试工具的使用 Python接口测试实战 ...

  6. 爬虫2.4-scrapy框架-图片分类下载

    目录 scrapy框架-图片下载 1 传统下载方法: 2 scrapy框架的下载方法 3 分类下载完整代码 scrapy框架-图片下载 python小知识: map函数:将一个可迭代对象的每个值,依次 ...

  7. Ryu学习总结(持续更新)

    Ryu学习总结 该篇学习笔记,与其他分析Ryu控制器代码的笔记不同,主要按照程序的构成来进行分块总结,由于本人为新手入门,不能保证没有错误,如果发现错误,欢迎指教. 以下的内容主要来源: 源码 官方文 ...

  8. Rest-Assured 测试框架

    Rest-Assured 是一个测试 Restful Web Service 的 Java 类库,我们能够测试各种各样的请求组合,依次测试核心业务逻辑的不同组合. 它是通过发送特定的rest api, ...

  9. Linux内核学习笔记(2)-- 父进程和子进程及它们的访问方法

    Linux系统中,进程之间有一个明显的继承关系,所有进程都是 PID 为1的 init 进程的后代.内核在系统启动的最后阶段启动 init 进程.该进程读取系统的初始化脚本(initscript)并执 ...

  10. UVA 11542 高斯消元

    从数组中选择几个数,要求他们的乘积可以开平方,问有多少种方案. 先将单个数拆分成质因子,对于这个数而言,那些指数为奇数的质因子会使这个数无法被开平方. 所以我们需要选择一个对应质因子指数为奇数的元素, ...