【DP】【期望】$P1850$换教室
题目描述
有 \(2n\) 节课程安排在$ n$ 个时间段上。在第 \(i\)(\(1 \leq i \leq n\))个时间段上,两节内容相同的课程同时在不同的地点进行,其中,牛牛预先被安排在教室 \(c_i\)上课,而另一节课程在教室 \(d_i\)进行。
在不提交任何申请的情况下,学生们需要按时间段的顺序依次完成所有的 \(n\)节安排好的课程。如果学生想更换第 \(i\)节课程的教室,则需要提出申请。若申请通过,学生就可以在第 $i $个时间段去教室 \(d_i\) 上课,否则仍然在教室 \(c_i\)上课。
牛牛发现申请更换第\(i\)节课程的教室时,申请被通过的概率是一个已知的实数 \(k_i\),并且对于不同课程的申请,被通过的概率是互相独立的。
所有的申请只能一次性提交,并且每个人只能选择至多 \(m\)节课程进行申请。
牛牛所在的大学有 \(v\)个教室,有 \(e\) 条道路。每条道路连接两间教室,并且是可以双向通行的。由于道路的长度和拥堵程度不同,通过不同的道路耗费的体力可能会有所不同。 当第 \(i\)(\(1 \leq i \leq n-1\))节课结束后,牛牛就会从这节课的教室出发,选择一条耗费体力最少的路径前往下一节课的教室。
现在牛牛想知道,申请哪几门课程可以使他因在教室间移动耗费的体力值的总和的期望值最小。
输入格式
第一行四个整数 \(n,m,v,e\)。
第二行 \(n\) 个正整数,第 \(i\)(\(1 \leq i \leq n\))个正整数表示 c\(c_i\),即第\(i\)个时间段牛牛被安排上课的教室;保证 \(1 \le c_i \le v\)。
第三行 \(n\) 个正整数,第 \(i\)(\(1 \leq i \leq n\))个正整数表示 \(d_i\),即第 $i $个时间段另一间上同样课程的教室;保证 \(1 \le d_i \le v\)。
第四行 \(n\) 个实数,第 \(i\)(\(1 \leq i \leq n\))个实数表示 \(k_i\),即牛牛申请在第 \(i\)个时间段更换教室获得通过的概率。保证 \(0 \le k_i \le 1\)。
接下来 \(e\) 行,每行三个正整数 \(a_j, b_j, w_j\),表示有一条双向道路连接教室 \(a_j, b_j\),通过这条道路需要耗费的体力值是 \(w_j\);保证 \(1 \le a_j, b_j \le v\), \(1 \le w_j \le 100\)。
保证 \(1 \leq n \leq 2000\),\(0 \leq m \leq 2000\),\(1 \leq v \leq 300\),\(0 \leq e \leq 90000\)。
保证通过学校里的道路,从任何一间教室出发,都能到达其他所有的教室。
保证输入的实数最多包含 \(3\)位小数。
输出格式
输出一行,包含一个实数,四舍五入精确到小数点后恰好\(2\)位,表示答案。你的输出必须和标准输出完全一样才算正确。
测试数据保证四舍五入后的答案和准确答案的差的绝对值不大于 \(4 \times 10^{-3}\)。 (如果你不知道什么是浮点误差,这段话可以理解为:对于大多数的算法,你可以正常地使用浮点数类型而不用对它进行特殊的处理)
样例
3 2 3 3
2 1 2
1 2 1
0.8 0.2 0.5
1 2 5
1 3 3
2 3 1
2.80
提示
- 道路中可能会有多条双向道路连接相同的两间教室。 也有可能有道路两端连接的是同一间教室。
- 请注意区分\(n,m,v,e\)的意义, \(n\)不是教室的数量, \(m\)不是道路的数量。
\(Solution\)
考虑DP。状态怎么设?显然第几节课需要在状态里。还要保证最多换\(m\)次,因此次数也要在状态里。那么,怎么从上一节课转移呢?显然如果我们不知道上一节课在哪个教室上的,就无法转移。因此,还要在加一维,记录当前是否申请换教室。
因此,状态就是\(f[i][j][k], 1 \leq i \leq n, 0 \leq j \leq m, 0 \leq k \leq 1\),表示前\(i\)节课,换了\(j\)次教室,第\(i\)次换或不换的期望。
至于转移则比较简单了
f[i][j][0] = min(f[i - 1][j][0] + w[c[i]][c[i - 1]],
f[i - 1][j][1] + w[c[i]][d[i - 1]] * k[i - 1]
+ w[c[i]][c[i - 1]] * (1 - k[i - 1]));
f[i][j][1] = min(f[i - 1][j - 1][0] + w[c[i]][c[i - 1]] * (1 - k[i]) + w[d[i]][c[i - 1]] * k[i],
f[i - 1][j - 1][1] + w[d[i]][d[i - 1]] * k[i - 1] * k[i]
+ w[c[i]][c[i - 1]] * (1 - k[i - 1]) * (1 - k[i])
+ w[c[i - 1]][d[i]] * (1 - k[i - 1]) * k[i]
+ w[d[i - 1]][c[i]] * k[i - 1] * (1 - k[i]));
如图为当前不选择换教室
如图为当前选择换教室
这道题还有几点需要主意的,在预处理部分。具体看代码
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
long long read(){
long long x = 0; int f = 0; char c = getchar();
while(c < '0' || c > '9') f |= c == '-', c = getchar();
while(c >= '0' && c <= '9') x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
return f? -x:x;
}
int n, m, V, E, c[2002], d[2002], w[305][305];
double f[2002][2002][2], k[2002], ans;
int main(){
memset(w, 63, sizeof w);//距离初始化
n = read(); m = read(); V = read(); E = read();
for(int i = 1; i <= n; ++i) c[i] = read();
for(int i = 1; i <= n; ++i) d[i] = read();
for(int i = 1; i <= n; ++i) scanf("%lf", &k[i]);
for(int i = 1; i <= E; ++i){
int x = read(), y = read(), z = read();
w[x][y] = w[y][x] = min(w[x][y], z);//有可能重边
}
for(int l = 1; l <= V; ++l)
for(int i = 1; i <= V; ++i)
for(int j = 1; j <= V; ++j)
w[i][j] = min(w[i][j], w[i][l] + w[l][j]);//floyed最短路
for(int i = 1; i <= V; ++i) w[i][i] = w[i][0] = w[0][i] = 0;//初始化
for(int i = 1; i <= n; ++i) f[i][0][0] = f[i - 1][0][0] + w[c[i]][c[i - 1]], f[i][0][1] = 1e9;
//初始化,处理一个也不申请的情况
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= m; ++j){
f[i][j][0] = min(f[i - 1][j][0] + w[c[i]][c[i - 1]],
f[i - 1][j][1] + w[c[i]][d[i - 1]] * k[i - 1]
+ w[c[i]][c[i - 1]] * (1 - k[i - 1]));
f[i][j][1] = min(f[i - 1][j - 1][0] + w[c[i]][c[i - 1]] * (1 - k[i])
+ w[d[i]][c[i - 1]] * k[i],
f[i - 1][j - 1][1] + w[d[i]][d[i - 1]] * k[i - 1] * k[i]
+ w[c[i]][c[i - 1]] * (1 - k[i - 1]) * (1 - k[i])
+ w[c[i - 1]][d[i]] * (1 - k[i - 1]) * k[i]
+ w[d[i - 1]][c[i]] * k[i - 1] * (1 - k[i]));
}
double ans = f[n][0][0];
for(int i = 1; i <= m; ++i) ans = min(ans, min(f[n][i][1], f[n][i][0]));//更新答案
printf("%.2lf", ans);
return 0;
}
【DP】【期望】$P1850$换教室的更多相关文章
- P1850 换教室[dp+期望]
流下了不会概率的眼泪,由于不会概率,转移少写了点东西... 这个dp很简单,就是一个普通的线性dp加点期望.(刚开始写这道题时信笔写下) \(dp[0/1][i][j]\)表示到第\(i\)个时间段时 ...
- [NOIP2016]换教室 D1 T3 Floyed+期望DP
[NOIP2016]换教室 D1 T3 Description 对于刚上大学的牛牛来说, 他面临的第一个问题是如何根据实际情况中情合适的课程. 在可以选择的课程中,有2n节课程安排在n个时间段上.在第 ...
- [NOIP2016]换教室(概率期望$DP$)
其实吧我老早就把这题切了--因为说实话,这道题确实不难啊--李云龙:比他娘的状压DP简单多了 今天我翻以前在Luogu上写的题解时,突然发现放错代码了,然后被一堆人\(hack\)--蓝瘦啊\(ORZ ...
- 【bzoj4720】[NOIP2016]换教室 期望dp
题目描述 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程.在可以选择的课程中,有2n节课程安排在n个时间段上.在第i(1≤i≤n)个时间段上,两节内容相同的课程同时在不同的 ...
- 【BZOJ4720】【NOIP2016】换教室 [期望DP]
换教室 Time Limit: 20 Sec Memory Limit: 512 MB[Submit][Status][Discuss] Description Input 第一行四个整数n,m,v ...
- 换教室(期望+DP)
换教室(期望+DP) \(dp(i,j,1/0)\)表示第\(i\)节课,申请了\(j\)次调换,这节课\(1/0\)调换. 换教室 转移的时候考虑: 上次没申请 这次也没申请 加上\(dis(fr[ ...
- 「NOIP2016」「P1850」 换教室(期望dp
题目描述 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程. 在可以选择的课程中,有 2n2n 节课程安排在 nn 个时间段上.在第 ii(1 \leq i \leq n1≤ ...
- Bzoj 4720 换教室 (期望DP)
刚发现Bzoj有Noip的题目,只会换教室这道题..... Bzoj 题面:Bzoj 4720 Luogu题目:P1850 换教室 大概是期望DPNoip极其友好的一道题目,DP不怎么会的我想到了,大 ...
- bzoj4720: [Noip2016]换教室(期望dp)
4720: [Noip2016]换教室 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1294 Solved: 698[Submit][Status ...
随机推荐
- 再谈初学者关心的ssh应用方方面面
http://blog.robertelder.org/what-is-ssh/ https://www.ssh.com/ssh/key/ 什么是ssh? ssh是一个在计算机之间实现安全通信的网络协 ...
- django中navie时间和aware时间详解
navie时间和aware时间: 什么是navie时间?什么是aware时间? navie时间:不知道自己的时间表示的是哪个时区的.也就是不知道自己几斤几两.比较幼稚. aware时间:知道自己的时间 ...
- loj#10078. 新年好(最短路)
题目: loj#10078. 新年好 解析: 亲戚只有五个,可以把它们看成2,3,4,5,6号点,分别跑最短路,记录一下距离,然后DFS一下 这题非常玄学,我开了一个\(12*12\)的数组,没有离散 ...
- vue路由切换时内容组件的滚动条回到顶部
在使用vue的时候会出现切换路由的时候滚动条保持在原来的位置,要切换路由的时候滚动条回到顶部才有更好的用户体验 1.当页面整体都要滚动到顶部的情况 router.afterEach(() => ...
- 去除vue项目地址栏中的#
在router文件夹下的index.js中的router实例中添加mode属性,值设置为history export default new Router({ mode:"history&q ...
- 从 Vue 的视角学 React(三)—— 事件处理
如果要处理某个元素的 click 事件,原生 js 可以直接为该元素添加一个 onclick 函数 Vue 封装了 v-on 指令,可以简化为 @click 并添加相应的函数 React 的开发思想是 ...
- python高级编程之 web静态服务器
返回固定数据 import socket def request_handler(new_client_socket): """ 响应客户端请求的核心函数 "& ...
- 半导体行业MES系统应用案例
半导体行业的发展是受惠在集成电路上的,但是收到技术瓶颈的阻碍,所以工业时期对半导体行业就造成了严重的冲击. 为了推动半导体行业快速发展,扭转像IBM.东芝以及富士康等IDM大厂利用晶圆代工对半导体制造 ...
- httpget请求测试用Java代码的实现方法
原文:http://www.cnblogs.com/johnson-yuan/p/6637906.html 1.首先要在eclipse中导入HttpClient的jar包. 2.新建类并写入一下代码: ...
- 关于升级.NetCore3.1启动运行项目之后无法运行之前版本的错误解决方案
昨天在跟上微软的进度,更新VS版本升级.netcore3.1 之后成功运行之后发现,我无法运行之前版本的问题 都是报这种问题: 还有打开解决方案所有的项目都无法正常加载,都是"已卸载&quo ...