【NOIP2016-D1T3】换教室
来源:互联网 发布:大数据支撑平台 编辑:程序博客网 时间:2024/05/21 15:25
【NOIP2016-D1T3】换教室
Description
Solution
emm,最近学习了一下期望。所以就回头把去年noip的题做一下。
这个题目描述很长,虽然说没有大段故事背景这类的废话,但是信息好分散啊。。。所以我们将这道题拆成几个部分分别看。
首先最水的就是Floyd,300的点数看到了颇有一种不做不爽的感觉。然后就是n节课每一节都有两种选择,有m个申请机会调换教室,并且相应的有K[i]的概率通过,最后要求给出申请后最短路径的期望值。
通过数据范围和从前往后的顺序性我们可以先试一试dp管不管用。令f[i][j][0/1]分别表示从第1节课到底i节课申请了j次之后第i节课申请与不申请的最大值(你要是能够断句也就明白了状态了)。
对于f[i][j][0],我们可以从f[i-1][j][0](前一节课没有申请)和f[i-1][j][1](前一节课申请调换)转移。需要注意的是,因为申请第i-1节调换有k[i]的概率通过,所以增加的路程就要乘以概率,这样才能得到期望。同理,将没有申请成功的路程乘以对应的概率,最后的累加才是这一种情况的值。
而f[i][j][1]就稍显复杂,同样是可以从f[i-1][j-1][0]和f[i-1][j-1][1]两个状态转移而来,但是这里我们要同时考虑前一节课申请的概率和本节课的概率,进而在f[i-1][j-1][1]时共有四个小部分。
最后枚举申请次数,取其中的最小值。
送上一组手打数据,拒绝图片样例:
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
这个题目描述很长,虽然说没有大段故事背景这类的废话,但是信息好分散啊。。。所以我们将这道题拆成几个部分分别看。
首先最水的就是Floyd,300的点数看到了颇有一种不做不爽的感觉。然后就是n节课每一节都有两种选择,有m个申请机会调换教室,并且相应的有K[i]的概率通过,最后要求给出申请后最短路径的期望值。
通过数据范围和从前往后的顺序性我们可以先试一试dp管不管用。令f[i][j][0/1]分别表示从第1节课到底i节课申请了j次之后第i节课申请与不申请的最大值(你要是能够断句也就明白了状态了)。
对于f[i][j][0],我们可以从f[i-1][j][0](前一节课没有申请)和f[i-1][j][1](前一节课申请调换)转移。需要注意的是,因为申请第i-1节调换有k[i]的概率通过,所以增加的路程就要乘以概率,这样才能得到期望。同理,将没有申请成功的路程乘以对应的概率,最后的累加才是这一种情况的值。
而f[i][j][1]就稍显复杂,同样是可以从f[i-1][j-1][0]和f[i-1][j-1][1]两个状态转移而来,但是这里我们要同时考虑前一节课申请的概率和本节课的概率,进而在f[i-1][j-1][1]时共有四个小部分。
最后枚举申请次数,取其中的最小值。
送上一组手打数据,拒绝图片样例:
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
CODE
#include<iostream>#include<cstring>#include<cstdio>using namespace std;inline int read(){char c;int rec=0;while((c=getchar())<'0'||c>'9');while(c>='0'&&c<='9')rec=rec*10+c-'0',c=getchar();return rec;}int n,m,V,E;int pp[2005],pn[2005];double K[2005];int map[305][305];inline void Floyed(){int i,j,k;for(i=1;i<=V;i++)map[i][i]=0;for (int k=1;k<=V;k++) for (int i=1;i<=V;i++) if (i!=k) for (int j=1;j<=V;j++) if (i!=j&&j!=k) map[i][j]=min(map[i][j],map[i][k]+map[k][j]);return ;}double ans=1e18;double f[2005][2005][2];int main(){n=read();m=read();V=read();E=read();for(int i=1;i<=n;i++)pp[i]=read();for(int i=1;i<=n;i++)pn[i]=read();for(int i=1;i<=n;i++)scanf("%lf",&K[i]);memset(map,0x3f,sizeof(map));for(int i=1;i<=E;i++){int x=read(),y=read(),z=read();map[x][y]=map[y][x]=min(map[x][y],z);}Floyed();for(int i=1;i<=n;i++)for(int j=0;j<=m;j++) f[i][j][0]=f[i][j][1]=1e12;f[1][0][0]=f[1][1][1]=0;for(int i=2;i<=n;i++){for(int j=0;j<=m;j++){int dpp=map[pp[i-1]][pp[i]],dpn=map[pp[i-1]][pn[i]];int dnp=map[pn[i-1]][pp[i]],dnn=map[pn[i-1]][pn[i]]; double p1=K[i-1],p2=K[i]; if(j<=i-1) f[i][j][0]=min(p1*dnp+(1-p1)*dpp+f[i-1][j][1], dpp+f[i-1][j][0]); if(j) f[i][j][1]=min(f[i-1][j-1][0]+p2*dpn+(1-p2)*dpp, f[i-1][j-1][1] +p1*p2*dnn+p1*(1-p2)*dnp +(1-p1)*p2*dpn+(1-p1)*(1-p2)*dpp);}}for(int i=0;i<=m&&i<=n;i++)ans=min(ans,min(f[n][i][0],f[n][i][1]));printf("%.2lf",ans);return 0;}定义几个中间变量,减少一下数组嵌套层数。
阅读全文
0 0
- 【NOIP2016-D1T3】换教室
- [NOIP2016 D1T3]换教室 【floyd+概率dp】
- [BZOJ]4720 换教室 [NOIP2016] D1T3 期望
- 【学术篇】NOIP2016 D1T3 luogu1850换教室
- noip2016 d1t3 换教室 期望dp+floyd
- NOIP 2016 D1T3换教室
- BZOJ4720 [Noip2016]换教室
- [NOIP2016]换教室
- [NOIP2016] 换教室
- 【noip2016】换教室 题解
- NOIP2016 换教室
- bzoj4720 [Noip2016]换教室
- NOIP2016换教室
- NOIP2016 T3 换教室
- NOIP2016 换教室
- bzoj4720: [Noip2016]换教室
- bzoj4720 [Noip2016]换教室
- noip2016换教室
- poj1273(最大流)
- 2017.08.15【NOIP 普及组】模拟赛C组 猴子拆房
- QT信号槽传递参数技巧
- C语言中的static 详细分析
- 并查集详解(模板)
- 【NOIP2016-D1T3】换教室
- poj-2395-Out of Hay-(Kruskal)
- [POJ](1789)Truck History ---最小生成树(图)
- 算法题练习系列之(二十七): 有理数四则运算
- Mybatis 初识
- 回调函数,函数指针
- 不受控制的 position-fixed
- 存储过程的例子(三)
- css3