题目链接: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. 201521123076 《Java程序设计》 第十四周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多数据库相关内容. 2. 书面作业 1. MySQL数据库基本操作 建立数据库,将自己的姓名.学号作为一条记录插入.(截图,需出现自 ...

  2. 201521123056 《Java程序设计》第12周学习总结

    1. 本周学习总结 2. 书面作业 将Student对象(属性:int id, String name,int age,double grade)写入文件student.data.从文件读出显示. 1 ...

  3. 201521123050 《Java程序设计》第13周学习总结

    1. 本周学习总结 2. 书面作业 1. 网络基础 1.1 比较ping www.baidu.com与ping cec.jmu.edu.cn,分析返回结果有何不同?为什么会有这样的不同? 对比可以看出 ...

  4. Android Studio不更新到最新版使用Kotlin

    第一步:安装Kotlin插件 打开Settings面板,找到Plugins选项,点击Browse repositories(浏览仓库),输入“Kotlin”查找,然后安装即可.安装完成之后需要重启An ...

  5. Maven第一篇【介绍、安装、结构目录】

    什么是Maven Maven是一个采用纯Java编写的开源项目管理工具, Maven采用了一种被称之为Project Object Model (POM)概念来管理项目,所有的项目配置信息都被定义在一 ...

  6. JSP第四篇【EL表达式介绍、获取各类数据、11个内置对象、执行运算、回显数据、自定义函数、fn方法库】

    什么是EL表达式? 表达式语言(Expression Language,EL),EL表达式是用"${}"括起来的脚本,用来更方便的读取对象! EL表达式主要用来读取数据,进行内容的 ...

  7. Oracle--新建用户以及赋予的权限

    1, 以dba方式登录Oracle 2, 创建用户,Users-->New ... 输入用户名和密码 3, 赋予connect/resource角色 4, 赋予该用户 对视图操作的相关权限 以下 ...

  8. JDBC操作数据库之批处理

    JDBC开发中,操作数据库需要和数据库建立连接,然后将要执行的SQL语句发送到数据库服务器,最后关闭数据库连接,都是按照这样的操做的,如果按照此流程要执行多条SQL语句,那么就要建立多个数据库连接,将 ...

  9. 0 can't find referenced pointcut declarePointExpress

    今天在用SpringAOP 的 @pointCut 的时候报错 Exception in thread "main" org.springframework.beans.facto ...

  10. windows10 下安装node失败 出现2502 2503的解决办法

    下载node出现以下异常    : the install has encountered an unexpected errer installing this package.this may i ...