洛谷P1850 换教室_数学期望_Floyd
调了一下午QAQ…让我对数学期望的理解又提升了一个层次。
首先,我们发现 v<=300v<=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的更多相关文章
- 洛谷——P1850 换教室
P1850 换教室 有 2n 节课程安排在 nn 个时间段上.在第 i个时间段上,两节内容相同的课程同时在不同的地点进行,其中,牛牛预先被安排在教室 $c_i$ 上课,而另一节课程在教室 $d_i$ ...
- 洛谷 P1850 换教室
P1850 换教室 题目描述 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程. 在可以选择的课程中,有 2n2n 节课程安排在 nn 个时间段上.在第 ii(1 \leq ...
- 洛谷 P1850 换教室 解题报告
P1850 换教室 题目描述 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程. 在可以选择的课程中,有\(2n\)节课程安排在\(n\)个时间段上.在第\(i(1≤i≤n) ...
- 洛谷P1850换教室
题目传送门 理解题意:给定你一个学期的课程和教室数量以及教室之间的距离还有换教室成功的概率,求一个学期走的距离的期望最小值 题目是有够恶心的,属于那种一看就让人不想刷的题目...很明显的动规,但是那个 ...
- 洛谷P1850 换教室 [noip2016] 期望dp
正解:期望dp 解题报告: 哇我发现我期望这块真的布星,可能在刷了点儿NOIp之后会去搞一波期望dp的题...感觉连基础都没有打扎实?基础概念都布星! 好那先把这题理顺了嗷qwq 首先我们看到期望就会 ...
- 洛谷P1850 换教室
令人印象深刻的状态转移方程... f[i][j][0/1]表示前i个换j次,第i次是否申请时的期望. 注意可能有重边,自环. 转移要分类讨论,距离是上/这次成功/失败的概率乘相应的路程. 从上次的0/ ...
- 洛谷P1850 换教室(概率dp)
传送门 我的floyd竟然写错了?今年NOIP怕不是要爆零了? 这就是一个概率dp 我们用$dp[i][j][k]$表示在第$i$个时间段,已经申请了$j$次,$k$表示本次换或不换,然后直接暴力转移 ...
- bzoj4720 / P1850 换教室(Floyd+期望dp)
P1850 换教室 先用Floyd把最短路处理一遍,接下来就是重头戏了 用 f [ i ][ j ][ 0/1 ] 表示在第 i 个时间段,发出了 j 次申请(注意不一定成功),并且在这个时间段是否( ...
- Luogu P1850 换教室(期望dp)
P1850 换教室 题意 题目描述 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程. 在可以选择的课程中,有\(2n\)节课程安排在\(n\)个时间段上.在第\(i(1\l ...
随机推荐
- 1、springboot+mybatis+zookeeper+dubbox+maven+pagehelper
一.创建普通的maven的web项目 2.配置KD42WF_Part1下的pom.xml <?xml version="1.0" encoding="UTF-8&q ...
- 【ACM】poj_2356_Find a multiple_201308061947
Find a multipleTime Limit: 1000MS Memory Limit: 65536K Total Submissions: 4988 Accepted: 2159 Spe ...
- 断路器-Hystrix的深入了解
前言 高可用相关的技术以及架构,对于大型复杂的分布式系统,是非常重要的.而高可用架构中,非常重要的一个环节,就是如何将分布式系统中的各个服务打造成高可用的服务,从而足以应对分布式系统环境中的各种各样的 ...
- Oracle动态显示日志
1.查看日志文件位置. IND_USER@PROD>select inst_id,name,value from v$diag_info; INST_ID NAME ...
- NYOJ_268_荷兰国旗问题
荷兰国旗问题 时间限制:3000 ms | 内存限制:65535 KB 难度:1 描写叙述 荷兰国旗有三横条块构成,自上到下的三条块颜色依次为红.白.蓝.现有若干由红.白.蓝三种颜色的条块序列.要 ...
- UVA - 10061 How many zero's and how many digits ?
n!=x*b^y, 当x为正整数时,最大的y就是n!末尾0的个数了, 把n,b分别拆成素因子相乘的形式: 比如, n=5,b=16 n=5,b=2^4, 非常明显,末尾0的个数为0 10进制时,n!= ...
- 数据库技术_Orcale技术(0002)_5分钟会用存储过程_存储过程实例
基础技术: 样例业务功能: 1.依据传入的类型A_TYPE联合查询PROCEDURE_TEST_A表.PROCEDURE_TEST_A_SUB表中的数据.并显示主要内容. 2.依据传入的类型A_TYP ...
- Swift - 将Data数据转换为[UInt8](bytes字节数组)
有时上传或者发送图片.文字时,需要将数据转换为 bytes 字节数组.下面介绍两种将 Data 转换为 [UInt8] 的方法. 假设我们有如下 Data 数据要转换: 1 let data = &q ...
- EOJ 2822 内存显示
一个 int 类型变量或 double 类型变量在连续几个字节的内存中存放.读取数值时,当数值中包含小数点时类型为 double,否则类型为 int.将读入的数值存放在 int 类型变量或 doubl ...
- Selenium之当鼠标悬浮时隐藏的元素才出现
在自动化过程中,有些导航按钮只有当鼠标悬浮在登录信息上时,它才能出现.这时候如果想要点击导航按钮直接用selenium的webDriver是无法定位的元素的,因为这些元素是隐藏的,只有鼠标悬浮时才出现 ...