调了一下午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. Codeforces 816C/815A - Karen and Game

    传送门:http://codeforces.com/contest/816/problem/C 本题是一个模拟问题. 有一个n×m的矩阵.最初,这个矩阵为零矩阵O.现有以下操作: a.行操作“row  ...

  2. Tp5 一次修改多个数据update

    //商城矿机设置 public function shop(){ if(!request()->isPost()){ return $this->fetch(); }else { $myd ...

  3. POJ 1061 BZOJ 1477 Luogu P1516 青蛙的约会 (扩展欧几里得算法)

    手动博客搬家: 本文发表于20180226 23:35:26, 原地址https://blog.csdn.net/suncongbo/article/details/79382991 题目链接: (p ...

  4. (13)处理静态资源(自定义资源映射)【从零开始学Spring Boot】

    上面我们介绍了Spring Boot 的默认资源映射,一般够用了,那我们如何自定义目录? 这些资源都是打包在jar包中的,然后实际应用中,我们还有很多资源是在管理系统中动态维护的,并不可能在程序包中, ...

  5. 1012关于SYSBENCH的用法

    sysbench安装.使用.结果解读 sysbench是一个模块化的.跨平台.多线程基准测试工具,主要用于评估测试各种不同系统参数下的数据库负载情况.目前sysbench代码托管在launchpad上 ...

  6. Android 自己定义TextView 实现文本间距

    转载请标明出处: http://blog.csdn.net/u011974987/article/details/50845269: Android系统中TextView默认显示中文时会比較紧凑.不是 ...

  7. HDU 4500

    哈哈,好爽好爽,刷水题报复社会啦... 哥这次省赛一定要拿一等奖,让你小看我,让你小看我.... #include <iostream> #include <cstdio> # ...

  8. vim下很好的右键复制方法

    1)先按shift ,然后鼠标选中即可复制:(shift按下时为非vim环境) 2)好方法: "Enable and disable mouse use noremap <f1> ...

  9. Tool-Java:Eclipse

    ylbtech-Tool-Java:Eclipse Eclipse 是一个开放源代码的.基于Java的可扩展开发平台.就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境.幸运的是,E ...

  10. ES6和Node容易搞混淆的点

    ES6 import  模块名 from XX  '模块标识符'     -----导入模块 import '路径 ' -----导入CSS样式 export default { }  和export ...