【NOIP2016提高组】 Day1 T3 换教室
题目链接:https://www.luogu.org/problemnew/show/P1850
此题正解为dp。
我们先用floyd处理出任意两个教室之间的距离,用dis[i][j]表示。
用f[i][j][0..1]表示在前i个课程中,用了j次换课的机会,第i节课选择换还是不换。
f[i][j][0]可以选择用f[i-1][j][0]更新(即第i-1节课选择不换课),代价为dis[c[i-1]][c[i]]。
同时,第i-1节课也可以选择换课,若换课成功,代价为dis[d[i-1]][c[i]],概率为k[i-1]。若换课不成功,则代价还是dis[c[i-1]][c[i]],概率为(1-k[i-1])。
则f[i][j][0]=min(f[i-1][j][0]+dis[c[i-1]][c[i]],(f[i-1][j-1][1]+dis[d[i-1]][c[i]])*k[i-1]+(f[i-1][j][0]+dis[c[i-1]][c[i]])*(1-k));
同理,f[i][j][1]可以选择用f[i-1][j][0]更新,若换课成功,代价为dis[c[i-1]][d[i]],概率为k[i]。若换课不成功,则代价是dis[c[i-1]][c[i]],概率为(1-k[i])。
同时,f[i][j][1]也可以选择用f[i-1][j][1]更新。
若两次换课均成功,代价为dis[d[i-1]][d[i]],概率为k[i]*k[i-1]。
若两次换课均不成功,代价为dis[c[i-1]][c[i]],概率为(1-k[i])*(1-k[i-1])。
若第i次成功而第i-1次不成功,代价为dis[c[i-1]][d[i]],概率为(1-k[i-1])*k[i]。
若第i次不成功而第i-1次成功,代价为dis[d[i-1]][c[i]],概率为k[i-1]*(1-k[i])。
则f[i][j][1]=min((f[i-1][j][0]+dis[c[i-1]][d[i]])*k[i]+(f[i-1][j][0]+dis[c[i-1]][c[i]])*(1-k[i]),f[i-1][j][1] + dis[d[i-1]][d[i]]*k[i]*k[i-1] + dis[c[i-1]][c[i]]*(1-k[i])*(1-k[i-1]) + dis[c[i-1]][d[i]]*(1-k[i-1])*k[i] + dis[d[i-1]][c[i]]*k[i-1]*(1-k[i]))。
可以看出每次转移是O(1)的,则时间复杂度为O(n*m)+O(v^3)。
最终结果为min(f[n][i][k]) i∈[0,m],j∈[0,1]。
#include<iostream>
#include<cstdio>
#include<cstring>
#define M 2002
using namespace std;
int n,m,v,e,c[M]={},d[M]={};
double p[M]={},dis[][]={},f[M][M][]={},minn=;
void pmin(double &x,double y){
x=min(x,y);
} int main(){
scanf("%d%d%d%d",&n,&m,&v,&e);
for(int i=;i<=n;i++) scanf("%d",c+i);
for(int i=;i<=n;i++) scanf("%d",d+i);
for(int i=;i<=n;i++) scanf("%lf",p+i);
for(int i=;i<=v;i++)
for(int j=;j<=v;j++) dis[i][j]=;
for(int i=;i<=e;i++){
int x,y,z;scanf("%d%d%d",&x,&y,&z);
pmin(dis[x][y],z); pmin(dis[y][x],z);
}
for(int i=;i<=v;i++) dis[i][i]=;
for(int k=;k<=v;k++)
for(int i=;i<=v;i++)
for(int j=;j<=v;j++)
dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
for(int i=;i<=n;i++)
for(int j=;j<=m;j++) f[i][j][]=f[i][j][]=;
f[][][]=; f[][][]=;
for(int i=;i<n;i++)
for(int j=;j<=min(i,m);j++){
pmin(f[i+][j][],f[i][j][]+dis[c[i]][c[i+]]);
double px;px=dis[c[i]][d[i+]]*p[i+]+dis[c[i]][c[i+]]*(-p[i+]);
pmin(f[i+][j+][],f[i][j][]+px);
px=dis[d[i]][c[i+]]*p[i]+dis[c[i]][c[i+]]*(-p[i]);
pmin(f[i+][j][],f[i][j][]+px);
px=dis[d[i]][d[i+]]*p[i]*p[i+]+dis[d[i]][c[i+]]*p[i]*(-p[i+])+dis[c[i]][d[i+]]*(-p[i])*p[i+]+dis[c[i]][c[i+]]*(-p[i])*(-p[i+]);
pmin(f[i+][j+][],f[i][j][]+px);
} for(int i=;i<=m;i++){
minn=min(minn,f[n][i][]);
minn=min(minn,f[n][i][]);
}
printf("%.2lf\n",minn);
}
【NOIP2016提高组】 Day1 T3 换教室的更多相关文章
- 【NOIP2016提高组day1】换教室
题目 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的 课程. 在可以选择的课程中,有 2n 节课程安排在 n 个时间段上. 在第 i ( 1 ≤ i ≤ n )个 时间段上,两 ...
- 【NOIP2016】Day1 T3 换教室(期望DP)
题目背景 NOIP2016 提高组 Day1 T3 题目描述 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程. 在可以选择的课程中,有 2n 节课程安排在 n 个时间段上. ...
- Noip2011 提高组 Day1 T3 Mayan游戏
题目描述 Mayan puzzle是最近流行起来的一个游戏.游戏界面是一个 7 行5 列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放在其他方块之上.游戏通关是指在规定 ...
- Noip2016 提高组 Day1
T1 玩具迷题 直通 思路: 1.首先根据数据范围来看,储存小人的姓名开一个二维char数组即可(不会开爆) 2.然后看他给出的样例以及条件什么的,能够确定出 ①朝内向右,朝外向左均为+ ②朝内向左, ...
- NOIP2016 DAY1 T3 换教室
换教室 Description 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程.在可以选择的课程中,有2n节 课程安排在n个时间段上.在第i(1≤i≤n)个时间段上,两节内 ...
- 2012Noip提高组Day1 T3 开车旅行
题目描述 小 A 和小 B 决定利用假期外出旅行,他们将想去的城市从 1 到 N 编号,且编号较小的 城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市 i 的海拔高度为 Hi,城市 ...
- NOIP2011提高组 Day1 T3 Mayan游戏
题目描述 Mayan puzzle是最近流行起来的一个游戏.游戏界面是一个7行×5列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放在其他方块之上.游戏通关是指在规定的步 ...
- 洛谷 3953 NOIP2017提高组Day1 T3 逛公园
[题解] 先建反向图,用dijkstra跑出每个点到n的最短距离dis[i] 设f[u][k]表示dis(u,n)<=mindis(u,n)+k的方案数.对于边e(u,v,w),走了这条边的话需 ...
- 【题解】NOIP2016提高组 复赛
[题解]NOIP2016提高组 复赛 传送门: 玩具谜题 \(\text{[P1563]}\) 天天爱跑步 \(\text{[P1600]}\) 换教室 \(\text{[P1850]}\) 组合数问 ...
随机推荐
- 201521123101 《Java程序设计》第2周学习总结
1. 本周学习总结 使用码云保存管理自己的代码: 学习String和Array: 继续对JAVA的探索,希望以后能在编程上更顺畅一些 2. 书面作业 1.使用Eclipse关联jdk源代码(截图),并 ...
- 201521145048《Java程序设计》第14周学习总结
1. 本周学习总结 1.1 以你喜欢式(思维导图或其他)归纳总结多数据库相关内容. 1.数据库的定义:是为了实现一定目的按某种规则组织起来的"数据"的"集合". ...
- 201521123059 《Java程序设计》第十周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常与多线程相关内容. 多线程的相关理解图: 2. 书面作业 本次PTA作业题集异常.多线程 Q1:finally 题目4-2 1. ...
- 从文本中读取内容并把读取到的内容转化成二进制保存的形式(包含十进制数如何转换成二进制数dtob函数)
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<malloc.h> d ...
- SpringMVC第一篇【介绍、入门、工作流程、控制器】
什么是SpringMVC? SpringMVC是Spring家族的一员,Spring是将现在开发中流行的组件进行组合而成的一个框架!它用在基于MVC的表现层开发,类似于struts2框架 为什么要使用 ...
- 浅谈SQL优化入门:1、SQL查询语句的执行顺序
1.SQL查询语句的执行顺序 (7) SELECT (8) DISTINCT <select_list> (1) FROM <left_table> (3) <join_ ...
- 传统编程和IoC的对比
ref:http://www.importnew.com/13619.html 传统编程:决定使用哪个具体的实现类的控制权在调用类本身,在编译阶段就确定了. IoC模式:调用类只依赖接口,而不依赖具体 ...
- Mybatis(1)
properties 标签的作用引入外部properties 文件的内容typeAliases 的作用可以用package这个标签批量给这个包下的所有类起一个别名 name属性写包的名字. 默认别名为 ...
- Apache POI
Apache POI 用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程式对Microsoft Office格式档案读和写的功能.POI为"Po ...
- AngularJS [ 快速入门教程 ]
前 序 S N AngularJS是什么? 我想既然大家查找AngularJS就证明大家多多少少对AngularJS都会有了解. AngularJS就是,使用JavaScript编写的客户 ...