题目链接: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 换教室的更多相关文章

  1. 【NOIP2016提高组day1】†换教室

    题目 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的 课程. 在可以选择的课程中,有 2n 节课程安排在 n 个时间段上. 在第 i ( 1 ≤ i ≤ n )个 时间段上,两 ...

  2. 【NOIP2016】Day1 T3 换教室(期望DP)

    题目背景 NOIP2016 提高组 Day1 T3 题目描述 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程. 在可以选择的课程中,有 2n 节课程安排在 n 个时间段上. ...

  3. Noip2011 提高组 Day1 T3 Mayan游戏

    题目描述 Mayan puzzle是最近流行起来的一个游戏.游戏界面是一个 7 行5 列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放在其他方块之上.游戏通关是指在规定 ...

  4. Noip2016 提高组 Day1

    T1 玩具迷题 直通 思路: 1.首先根据数据范围来看,储存小人的姓名开一个二维char数组即可(不会开爆) 2.然后看他给出的样例以及条件什么的,能够确定出 ①朝内向右,朝外向左均为+ ②朝内向左, ...

  5. NOIP2016 DAY1 T3 换教室

    换教室 Description 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程.在可以选择的课程中,有2n节 课程安排在n个时间段上.在第i(1≤i≤n)个时间段上,两节内 ...

  6. 2012Noip提高组Day1 T3 开车旅行

    题目描述 小 A 和小 B 决定利用假期外出旅行,他们将想去的城市从 1 到 N 编号,且编号较小的 城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市 i 的海拔高度为 Hi,城市 ...

  7. NOIP2011提高组 Day1 T3 Mayan游戏

    题目描述 Mayan puzzle是最近流行起来的一个游戏.游戏界面是一个7行×5列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放在其他方块之上.游戏通关是指在规定的步 ...

  8. 洛谷 3953 NOIP2017提高组Day1 T3 逛公园

    [题解] 先建反向图,用dijkstra跑出每个点到n的最短距离dis[i] 设f[u][k]表示dis(u,n)<=mindis(u,n)+k的方案数.对于边e(u,v,w),走了这条边的话需 ...

  9. 【题解】NOIP2016提高组 复赛

    [题解]NOIP2016提高组 复赛 传送门: 玩具谜题 \(\text{[P1563]}\) 天天爱跑步 \(\text{[P1600]}\) 换教室 \(\text{[P1850]}\) 组合数问 ...

随机推荐

  1. 201521123097《Java程序设计》第二周学习总结

    1.本周学习总结 (1)学习了java的一些类型和变量. (2)学习了码云的部分功能的使用. 2.书面作业 使用Eclipse关联jdk源代码,并查看String对象的源代码. 为什么要尽量频繁的对字 ...

  2. 201521123098 JAVA课程设计

    1.团队课程设计博客链接 http://www.cnblogs.com/agts/p/7067948.html 2.个人负责模块或任务说明 个人任务:实现初始界面中的登录.注册模块,以及数据库的连接和 ...

  3. 201521123113《Java程序设计》第9周学习总结

    1. 本周学习总结 2. 书面作业 本次PTA作业题集异常 Q1.常用异常 题目5-1 1.1 截图你的提交结果(出现学号) 1.2 自己以前编写的代码中经常出现什么异常.需要捕获吗(为什么)?应如何 ...

  4. 数据结构与算法->树->2-3-4树的查找,添加,删除(Java)

    代码: 兵马未动,粮草先行 作者: 传说中的汽水枪 如有错误,请留言指正,欢迎一起探讨. 转载请注明出处. 目录 一. 2-3-4树的定义 二. 2-3-4树数据结构定义 三. 2-3-4树的可以得到 ...

  5. cnpack热键

    CnPack的热键为ALt+space,当不自动补齐时按下Alt+space则会补齐

  6. java.lang.IllegalArgumentException: object is not an instance of declaring class

    今天在使用反射的时候,出现了java.lang.IllegalArgumentException: object is not an instance of declaring class错误-具体是 ...

  7. JDBC在javaweb中的应用之分页数据查询

    分页查询 分页查询是java web开发中经常使用到的技术.在数据库中数据量非常大的情况下,不适合将所有的数据全部显示到一个页面中,同时为了节约程序以及数据库的资源,就需要对数据进行分页查询操作. 通 ...

  8. Log Reservation

    本文是在阅读<SQL Server Transaction Log Management>的Chapter 2: Log Internals时发现以往对Log Grows的理解比较片面,大 ...

  9. Extjs2.0 desktop 动态创建桌面图标和开始菜单

    这几天一直纠结Extjs desktop怎么动态读取数据,用Ext.net已经实现但是不灵活.Ext.net做出来的桌面在窗口关闭后只是隐藏该窗口,并没有释放,对于我这种js菜鸟来说,改那一坨代码要人 ...

  10. php调用webservice接口

    项目中使用到了调用三方厂商webService接口.他的接口类似为http://haha.cn:86/BaseInfoService.svc?wsdl,在这里我注意到了"wsdl" ...