[NOIp2016] 换教室
题目类型:期望\(DP\)
传送门:>Here<
题意:现有\(N\)个时间段,每个时间段上一节课。如果不申请换教室,那么时间段\(i\)必须去教室\(c[i]\)上课,如果申请换课成功,那么就可以去教室\(d[i]\)上课。第\(i\)节课申请换教室成功的概率是\(k[i]\)。每个教室是无向图的一个节点,从一个教室到另一个教室需要耗费的体力是它们之间的最短路。现在,你最多可以申请换\(M\)节课,问耗费体力值最少的期望
解题思路
题意比较复杂。时间段不如理解为时间点。可以概括为:第\(i\)个时间点要么在\(c[i]\)要么在\(d[i]\),并且到\(d[i]\)去的期望是\(k[i]\)。也就是说申请不成功的概率是\(1-k[i]\)
由于教室最多只有\(300\)间,因此最短路直接用\(Floyd\)处理即可。
然后考虑进行期望\(DP\)。容易想到设\(dp[i][j]\)表示前\(i\)个时间点里,申请\(j\)次的耗费体力值最少的期望。然而我们发现这样设非常难转移,因为我们不知道上一节课有没有换教室。
因此我们增加一维:\(dp[i][j][k]\)表示前\(i\)个时间点里,申请\(j\)次,并且\(k=0\)第\(i\)个时间点在\(c[i]\),\(k=1\)则在\(d[i]\)。这样就可以转移了
由于已经转化为\(DP\)问题,因此我们只需要考虑状态。分开考虑:
\]
对于\(dp[i][j][0]\)的转移,我们确定了在第\(i\)个时间点一定在教室\(c[i]\),而起点却不确定。分开考虑乘上概率即可
\]
第二个方程实在太长了(放不下……),可以见代码。总体思想还是和前面差不多,不一样的是\(dp[i][j][1]\)不能代表第\(i\)个时间点在教室\(d[i]\),而是都有可能,因此从\(dp[i-1][j-1][1]\)转移过来时要分四类讨论
Code
注意\(j=0\)也是要讨论的。另外,刚开始\(dp\)数组应该无限大,这样才能在转移时自动排除不可能的情况
/*By DennyQi 2018*/
#include <cstdio>
#include <queue>
#include <cstring>
#include <algorithm>
#define r read()
using namespace std;
typedef long long ll;
const int MAXN = 2010;
const int MAXM = 20010;
const int INF = 1061109567;
inline int read(){
int x = 0; int w = 1; register char c = getchar();
for(; c ^ '-' && (c < '0' || c > '9'); c = getchar());
if(c == '-') w = -1, c = getchar();
for(; c >= '0' && c <= '9'; c = getchar()) x = (x<<3) + (x<<1) + c - '0'; return x * w;
}
int N,M,V,E,x,y,z;
int c[MAXN],d[MAXN],dis[305][305];
double k[MAXN],dp[MAXN][MAXN][2],ans;
int main(){
// freopen(".in","r",stdin);
memset(dis, 0x3f, sizeof(dis));
N = r, M = r, V = r, E = r;
for(int i = 1; i <= V; ++i) dis[i][i] = 0;
for(int i = 1; i <= N; ++i) c[i] = r;
for(int i = 1; i <= N; ++i) d[i] = r;
for(int i = 1; i <= N; ++i) scanf("%lf", k+i);
for(int i = 1; i <= E; ++i){
x = r, y = r, z = r;
dis[x][y] = min(dis[x][y], z);
dis[y][x] = min(dis[y][x], z);
}
for(int K = 1; K <= V; ++K){
for(int i = 1; i <= V; ++i){
for(int j = 1; j <= V; ++j){
dis[i][j] = min(dis[i][j], dis[i][K] + dis[K][j]);
}
}
}
for(int i = 1; i <= N; ++i){
for(int j = 0; j <= M; ++j){
dp[i][j][0] = dp[i][j][1] = 99999999.999;
}
}
dp[1][0][0] = dp[1][1][1] = 0;
for(int i = 2; i <= N; ++i){
dp[i][0][0] = dp[i-1][0][0] + dis[c[i-1]][c[i]];
for(int j = 1; j <= min(i,M); ++j){
dp[i][j][0] = min(dp[i-1][j][0] + dis[c[i-1]][c[i]], dp[i-1][j][1] + (1-k[i-1])*dis[c[i-1]][c[i]] + k[i-1]*dis[d[i-1]][c[i]]);
dp[i][j][1] = min(dp[i-1][j-1][0] + (1-k[i])*dis[c[i-1]][c[i]] + k[i]*dis[c[i-1]][d[i]], dp[i-1][j-1][1] + (1-k[i-1])*(1-k[i])*dis[c[i-1]][c[i]] + (1-k[i-1])*k[i]*dis[c[i-1]][d[i]] + k[i-1]*(1-k[i])*dis[d[i-1]][c[i]] + k[i-1]*k[i]*dis[d[i-1]][d[i]]);
}
}
ans = 9999999.999;
for(int j = 0; j <= M; ++j){
ans = min(ans, min(dp[N][j][0], dp[N][j][1]));
}
printf("%.2f", ans);
return 0;
}
[NOIp2016] 换教室的更多相关文章
- [NOIP2016]换教室 D1 T3 Floyed+期望DP
[NOIP2016]换教室 D1 T3 Description 对于刚上大学的牛牛来说, 他面临的第一个问题是如何根据实际情况中情合适的课程. 在可以选择的课程中,有2n节课程安排在n个时间段上.在第 ...
- BZOJ 4720 [Noip2016]换教室
4720: [Noip2016]换教室 Description 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程.在可以选择的课程中,有2n节课程安排在n个时间段上.在第i( ...
- 【BZOJ】4720: [Noip2016]换教室
4720: [Noip2016]换教室 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1690 Solved: 979[Submit][Status ...
- bzoj4720: [Noip2016]换教室(期望dp)
4720: [Noip2016]换教室 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1294 Solved: 698[Submit][Status ...
- [NOIP2016]换教室 题解(奇怪的三种状态)
2558. [NOIP2016]换教室 [题目描述] 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程. 在可以选择的课程中,有2n节课程安排在n个时间段上.在第i(1< ...
- 【bzoj4720】[NOIP2016]换教室
题目描述 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程.在可以选择的课程中,有2n节课程安排在n个时间段上.在第i(1≤i≤n)个时间段上,两节内容相同的课程同时在不同的 ...
- [NOIP2016]换教室(概率期望$DP$)
其实吧我老早就把这题切了--因为说实话,这道题确实不难啊--李云龙:比他娘的状压DP简单多了 今天我翻以前在Luogu上写的题解时,突然发现放错代码了,然后被一堆人\(hack\)--蓝瘦啊\(ORZ ...
- 【bzoj4720】[NOIP2016]换教室 期望dp
题目描述 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程.在可以选择的课程中,有2n节课程安排在n个时间段上.在第i(1≤i≤n)个时间段上,两节内容相同的课程同时在不同的 ...
- NOIP2016换教室 BZOJ 4720
BZOJ 4720 换教室 题目描述: 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程.在可以选择的课程中,有2n节 课程安排在n个时间段上.在第i(1≤i≤n)个时间段上 ...
随机推荐
- 1.SDL介绍
01.什么是SDL SDL是微软提出的一种软件开发安全生命周期管理的一种最佳安全实践,全称为Security Development Lifecycle. SDL是微软软件开发安全保障流程,结合了软件 ...
- offic|集成|协同OA|移动办公|
随着互联网时代的日新月异,移动通讯技术的飞速发展,移动网络技术的更新换代,手机.平板电脑等移动设备越来越智能化.越来越多样化,人们对移动办公的需求也在日益增长.在此背景下北京博信施科技有限公司自主研发 ...
- 英语口语练习系列-C11-了解
词汇 actor [ˈæktə(r)] n. 男演员 He is a good actor. 他是一个好演员. afternoon [ˌɑ:ftəˈnu:n] n. 下午 a boring after ...
- 验证二叉搜索树的golang实现
给定一个二叉树,判断其是否是一个有效的二叉搜索树. 一个二叉搜索树具有如下特征: 节点的左子树只包含小于当前节点的数. 节点的右子树只包含大于当前节点的数. 所有左子树和右子树自身必须也是二叉搜索树. ...
- Nginx健康检查模块
在本小节我们介绍一个用于Nginx对后端UpStream集群节点健康状态检查的第三方模块:nginx_upstream_check_module(https://github.com/yaoweibi ...
- Jetson TX2(1)ubutu1604--安装Nvidia Linux驱动
https://www.jianshu.com/p/c8ebe4aaa708 系统开机首次进入的是以nvidia用户登录的Ubuntu 命令行界面.Nvidia 驱动安装 通过sudo su 输入密码 ...
- leetcode 203. Remove Linked List Elements 、83. Remove Duplicates from Sorted List 、82. Remove Duplicates from Sorted List II(剑指offer57 删除链表中重复的结点)
203题是在链表中删除一个固定的值,83题是在链表中删除重复的数值,但要保留一个:82也是删除重复的数值,但重复的都删除,不保留. 比如[1.2.2.3],83题要求的结果是[1.2.3],82题要求 ...
- JS检测浏览器是否最大化
function isFullScreen (){ if( window.outerHeight === screen.availHeight ){ i ...
- Django view(视图)
在Django MTV模式中,View视图负责业务逻辑部分,路由系统接收到HTTP请求,并将任务分配给相应的视图函数,由视图函数来负责响应这个请求.无论视图本身包含什么逻辑,都要返回响应. 在这里HT ...
- fliplr函数
fliplr 左右翻转矩阵 语法: B = fliplr(A) 将矩阵A的列绕垂直轴进行左右翻转 matabc 如果A是一个行向量,fliplr(A)将A中元素的顺序进行翻转. 如果A是一个列向量, ...