调了一下午QAQ…让我对数学期望的理解又提升了一个层次。
首先,我们发现 v&lt;=300v&lt;=300v<=300 , 这样我们就可以用 FloydFloydFloyd 算法来 O(n3)O(n^3)O(n3) 处理出任意两点间的最短路。
对于题目,我们不难列出状态dp[i][j][0/1]dp[i][j][0/1]dp[i][j][0/1]。
这个状态代表:走到第iii个点,用了jjj次机会,当前使用了(0表示未使用,1表示使用)机会的最小期望值。
首先,我们考虑dp[i][j][0]dp[i][j][0]dp[i][j][0],那么上一个点可能使用了机会,也可能未使用机会。
不难列出未使用机会的方程:

dp[i][j][0]=dp[i−1][j][0]+f[ci−1][ci]dp[i][j][0]=dp[i-1][j][0]+f[c_{i-1}][c_{i}]dp[i][j][0]=dp[i−1][j][0]+f[ci−1​][ci​]

那么对于上一次使用了机会,方程应为:

dp[i][j][0]=dp[i−1][j][1]+f[ci−1][ci]∗(1−k[i−1])+f[di−1][ci]∗k[i−1]dp[i][j][0]=dp[i-1][j][1] + f[c_{i-1}][c_{i}] * (1 - k[i-1]) + f[
d_{i-1}][c_{i}] * k[i-1]dp[i][j][0]=dp[i−1][j][1]+f[ci−1​][ci​]∗(1−k[i−1])+f[di−1​][ci​]∗k[i−1]

体会一下,上一次使用机会的话会面临两种情况:
1.交换成功,路程为f[di−1][ci]f[d_{i-1}][c_{i}]f[di−1​][ci​],概率为k[i−1]k[i-1]k[i−1].
2.未交换成功,路程为f[ci−1][ci]f[c_{i-1}][c_{i}]f[ci−1​][ci​],概率为1−k[i−1]1-k[i-1]1−k[i−1].

再考虑一下当前使用机会,分6种情况。
1.上一轮未交换,当前交换失败:路程为f[ci−1][ci]f[c_{i-1}][c_{i}]f[ci−1​][ci​],概率为1−k[i]1-k[i]1−k[i]
2.上一轮未交换,当前交换成功:路程为f[ci−1][di]f[c_{i-1}][d_{i}]f[ci−1​][di​],概率为k[i]k[i]k[i]
3.上一轮交换失败,当前交换失败,路程为f[ci−1][ci]f[c_{i-1}][c_{i}]f[ci−1​][ci​],概率为(1−k[i−1])∗(1−k[i])(1-k[i-1])*(1-k[i])(1−k[i−1])∗(1−k[i])
4.上一轮交换失败,当前交换成功,路程为f[ci−1][di]f[c_{i-1}][d_{i}]f[ci−1​][di​],概率为(1−k[i−1])∗k[i](1-k[i-1])*k[i](1−k[i−1])∗k[i]
5.上一轮交换成功,当前交换失败,路程为f[di−1][ci]f[d_{i-1}][c_{i}]f[di−1​][ci​],概率为k[i−1]∗(1−k[i])k[i-1]*(1-k[i])k[i−1]∗(1−k[i])
6.上一轮交换成功,当前交换成功,路程为f[di−1][di]f[d_{i-1}][d_{i}]f[di−1​][di​],概率为k[i−1]∗k[i]k[i-1]*k[i]k[i−1]∗k[i]
最后将所有信息合并即可,另外细节巨多,到注意初始化。
Code:

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 350;
const int N = 2000 + 5;
const double inf = 1000000000;
int f[maxn][maxn], c[N], d[N], n,m,v,e;
double k[N], dp[N][N][2];
inline void update(double &a, double b){ if(b < a) a = b;}
int main()
{
scanf("%d%d%d%d",&n,&m,&v,&e);
for(int i = 1;i <= n; ++i) scanf("%d",&c[i]);
for(int i = 1;i <= n; ++i) scanf("%d",&d[i]);
for(int i = 1;i <= n; ++i) scanf("%lf",&k[i]);
for(int i = 1;i <= v; ++i) for(int j = 1;j <= v; ++j) f[i][j] = f[j][i] = inf;
for(int i = 1;i <= e; ++i)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
f[a][b] = f[b][a] = min(f[a][b], c);
}
for(int i = 0;i <= v; ++i) f[i][0] = f[0][i] = f[i][i] = 0;
for(int k = 1;k <= v; ++k)
for(int i = 1;i <= v; ++i)
for(int j = 1;j <= v; ++j)
if(f[i][k] != inf && f[k][j] != inf)f[i][j] = min(f[i][j], f[i][k] + f[k][j]);
for (int i = 0; i <= n; ++i)
for (int j = 0; j <= m; ++j)dp[i][j][0] = dp[i][j][1] = inf;
dp[1][0][0] = dp[1][1][1] = dp[0][0][0] = 0;
for(int i = 1;i <= n; ++i)
{
dp[i][0][0] = dp[i-1][0][0] + f[c[i-1]][c[i]];
for(int j = 1;j <= min(i,m); ++j)
{
update(dp[i][j][0], dp[i-1][j][0] + f[c[i-1]][c[i]]);
update(dp[i][j][0], dp[i-1][j][1] + f[c[i-1]][c[i]] * (1 - k[i-1]) + f[d[i-1]][c[i]] * k[i-1]);
if(j >= 1)
{
double tmp = 0.0;
update(dp[i][j][1], dp[i-1][j-1][0] + f[c[i-1]][d[i]] * k[i] + f[c[i-1]][c[i]] * (1 - k[i]));
tmp = dp[i-1][j-1][1];
tmp += f[c[i-1]][c[i]] * (1 - k[i-1]) * (1 - k[i]);
tmp += f[d[i-1]][c[i]] * k[i-1] * (1 - k[i]);
tmp += f[c[i-1]][d[i]] * (1 - k[i-1]) * k[i];
tmp += f[d[i-1]][d[i]] * k[i-1] * k[i];
update(dp[i][j][1], tmp);
}
}
}
double ans = inf;
for(int j = 0;j <= m; ++j)
{
update(ans, dp[n][j][0]);
update(ans, dp[n][j][1]);
}
printf("%.2f",ans);
return 0;
}

洛谷P1850 换教室_数学期望_Floyd的更多相关文章

  1. 洛谷——P1850 换教室

    P1850 换教室 有 2n 节课程安排在 nn 个时间段上.在第 i个时间段上,两节内容相同的课程同时在不同的地点进行,其中,牛牛预先被安排在教室 $c_i$​ 上课,而另一节课程在教室 $d_i$ ...

  2. 洛谷 P1850 换教室

    P1850 换教室 题目描述 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程. 在可以选择的课程中,有 2n2n 节课程安排在 nn 个时间段上.在第 ii(1 \leq ...

  3. 洛谷 P1850 换教室 解题报告

    P1850 换教室 题目描述 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程. 在可以选择的课程中,有\(2n\)节课程安排在\(n\)个时间段上.在第\(i(1≤i≤n) ...

  4. 洛谷P1850换教室

    题目传送门 理解题意:给定你一个学期的课程和教室数量以及教室之间的距离还有换教室成功的概率,求一个学期走的距离的期望最小值 题目是有够恶心的,属于那种一看就让人不想刷的题目...很明显的动规,但是那个 ...

  5. 洛谷P1850 换教室 [noip2016] 期望dp

    正解:期望dp 解题报告: 哇我发现我期望这块真的布星,可能在刷了点儿NOIp之后会去搞一波期望dp的题...感觉连基础都没有打扎实?基础概念都布星! 好那先把这题理顺了嗷qwq 首先我们看到期望就会 ...

  6. 洛谷P1850 换教室

    令人印象深刻的状态转移方程... f[i][j][0/1]表示前i个换j次,第i次是否申请时的期望. 注意可能有重边,自环. 转移要分类讨论,距离是上/这次成功/失败的概率乘相应的路程. 从上次的0/ ...

  7. 洛谷P1850 换教室(概率dp)

    传送门 我的floyd竟然写错了?今年NOIP怕不是要爆零了? 这就是一个概率dp 我们用$dp[i][j][k]$表示在第$i$个时间段,已经申请了$j$次,$k$表示本次换或不换,然后直接暴力转移 ...

  8. bzoj4720 / P1850 换教室(Floyd+期望dp)

    P1850 换教室 先用Floyd把最短路处理一遍,接下来就是重头戏了 用 f [ i ][ j ][ 0/1 ] 表示在第 i 个时间段,发出了 j 次申请(注意不一定成功),并且在这个时间段是否( ...

  9. Luogu P1850 换教室(期望dp)

    P1850 换教室 题意 题目描述 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程. 在可以选择的课程中,有\(2n\)节课程安排在\(n\)个时间段上.在第\(i(1\l ...

随机推荐

  1. Python 设置字体样式

    # 1.先导入分别可指定单元格字体相关,颜色,和对齐方式的类 from openpyxl.styles import Font, colors, Alignment # 2.配置字体格式为:样式(Ti ...

  2. python下的线程 进程,以及如何实现并发服务器

    在一个CPU(一核)的电脑上, 程序的运行是并发运行的,调度的算法叫时间片轮转法,也叫轮询法 在多CPU(多核)的电脑上,一个CPU跑一个程序,刚程序运行数量小于核心数时,程序是并行的 并发:看上去一 ...

  3. 【ACM】nyoj_540_奇怪的排序_201308050951

    奇怪的排序时间限制:1000 ms  |  内存限制:65535 KB 难度:1描述 最近,Dr. Kong 新设计一个机器人Bill.这台机器人很聪明,会做许多事情.惟独对自然数的理解与人类不一样, ...

  4. HDU 4530

    今天让人看不起了,话说好伤心,说我搞了ACM那么久都没获得拿得出手的奖.... 今晚爷爷我要狂刷2013腾讯马拉松的水题,奶奶滴,哈哈哈哈...T_T #include <iostream> ...

  5. arm32位固定指令中怎么容纳32位变量

    在ARM指令集汇编码中.32位有效马上数是通过______偶数位而间接得到的 A.循环左移 B.循环右移. C.逻辑左移. D.逻辑右移 答案为循环左移.为什么?还有最好解释一下逻辑移动和循环移动的概 ...

  6. UVA - 11077 Find the Permutations (置换)

    Sorting is one of the most usedoperations in real life, where Computer Science comes into act. It is ...

  7. HDU 5218 The E-pang Palace (简单几何—2014广州现场赛)

    题目链接:pid=5128">http://acm.hdu.edu.cn/showproblem.php? pid=5128 题面: The E-pang Palace Time Li ...

  8. C语言 - .c和.h文件的困惑

    本质上没有任何区别. 只不过一般:.h文件是头文件,内含函数声明.宏定义.结构体定义等内容. .c文件是程序文件,内含函数实现,变量定义等内容.而且是什么后缀也没有关系,只不过编译器会默认对某些后缀的 ...

  9. php手机号码验证正则表达式

    移动:134.135.136.137.138.139.150.151.152.157.158.159.182.183.184.187.188.178(4G).147(上网卡): 联通:130.131. ...

  10. docker(三):Harbor 1.8.0 仓库的安装和使用

    回顾: docker(一):docker是什么? docker(二):CentOS安装docker docker(部署常见应用):docker部署mysql 安装的先决条件 硬件环境 1.CPU    ...