传送门

Description

对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程。

在可以选择的课程中,有 $ 2n $ 节课程安排在 $ n $ 个时间段上。在第 $ i $个时间段上 $ (1 \leq i \leq n) $,两节内容相同的课程同时在不同的地点进行,其中,牛牛预先被安排在教室 $ c_i $ 上课,而另一节课程在教室 $ d_i $ 进行。

在不提交任何申请的情况下,学生们需要按时间段的顺序依次完成所有的 $ n $ 节安排好的课程。如果学生想更换第i节课程的教室,则需要提出申请。若申请通过,学生就可以在第 $ i $ 个时间段去教室 $ d_i $ 上课,否则仍然在教室 $ c_i $ 上课。

由于更换教室的需求太多,申请不一定能获得通过。通过计算,牛牛发现申请更换第 $ i $ 节课程的教室时,申请被通过的概率是一个已知的实数 $ k_i $,并且对于不同课程的申请,被通过的概率是互相独立的。

学校规定,所有的申请只能在学期开始前一次性提交,并且每个人只能选择至多 $ m $ 节课程进行申请。这意味着牛牛必须一次性决定是否申请更换每节课的教室,而不能根据某些课程的申请结果来决定其他课程是否申请;牛牛可以申请自己最希望更换教室的 $ m $ 门课程,也可以不用完这 $ m $ 个申请的机会,甚至可以一门课程都不申请。

因为不同的课程可能会被安排在不同的教室进行,所以牛牛需要利用课问时间从一间教室赶到另一间教室。

牛牛所在的大学有 $ v $ 个教室,有 $ e $ 条道路。每条道路连接两间教室,并且是可以双向通行的。由于道路的长度和拥堵程度不同,通过不同的道路耗费的体力可能会有所不同。当第 $ i \((\) 1 \leq i \leq n - 1 $)节课结束后,牛牛就会从这节课的教室出发,选择一条耗费体力最少的路径前往下一节课的教室。

现在牛牛想知道,申请哪几门课程可以使他因在教室间移动耗费的体力值的总和的期望值最小,请你帮他求出这个最小值。

Solution

\(floyed\)算出每个教室之间的最短路

\(f_{i,j,0/1}\)表示前\(i\)个教室,申请了\(j\)个,第\(i\)间教室有无申请的期望值

考虑第\(i-1\)个教室是否有选进行转移即可

Code 

#include<bits/stdc++.h>
#define ll long long
#define db double
#define dbg1(x) cerr<<#x<<"="<<(x)<<" "
#define dbg2(x) cerr<<#x<<"="<<(x)<<"\n"
#define dbg3(x) cerr<<#x<<"\n"
using namespace std;
#define reg register
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
const int MN=2005,MV=305;
const db inf=1e30;
db p[MN],f[MN][MN][2];
int d[MN][MN];
int N,M,V,E,C[MN],D[MN];
#define rw(x,y) x=min(x,y)
int main()
{
memset(d,0x3f,sizeof d);
N=read(),M=read(),V=read(),E=read();
reg int i,j,k,x,y,z;
for(i=1;i<=N;++i)C[i]=read();
for(i=1;i<=N;++i)D[i]=read();
for(i=1;i<=N;++i)scanf("%lf",&p[i]);
for(i=1;i<=E;++i)
x=read(),y=read(),z=read(),
rw(d[x][y],z),rw(d[y][x],z); for(k=1;k<=V;++k)for(i=1;i<=V;++i)for(j=1;j<=V;++j)
rw(d[i][j],d[i][k]+d[k][j]);
for(i=1;i<=V;++i)d[i][0]=d[0][i]=d[i][i]=0;
for(i=1;i<=N;++i)for(j=0;j<=M;++j)f[i][j][0]=f[i][j][1]=inf;
for(i=1;i<=N;++i)for(j=0;j<=M&&j<=i;++j)
{
if(i-2>=j)rw(f[i][j][0],f[i-1][j][0]+d[C[i-1]][C[i]]);
if(i-1>=j)rw(f[i][j][0],f[i-1][j][1]+d[C[i-1]][C[i]]*(1-p[i-1])+d[D[i-1]][C[i]]*p[i-1]);
if(i-1>=j&&j>0)rw(f[i][j][1],f[i-1][j-1][0]+d[C[i-1]][D[i]]*p[i]+d[C[i-1]][C[i]]*(1-p[i]));
if(j>0)rw(f[i][j][1],f[i-1][j-1][1]+d[C[i-1]][C[i]]*(1-p[i-1])*(1-p[i])+
d[C[i-1]][D[i]]*(1-p[i-1])*p[i]+d[D[i-1]][C[i]]*p[i-1]*(1-p[i])+d[D[i-1]][D[i]]*p[i-1]*p[i]);
}
db ans=inf;
for(i=0;i<=M;++i)rw(ans,f[N][i][0]),rw(ans,f[N][i][1]);
printf("%.2lf\n",ans);
}

Blog来自PaperCloud,未经允许,请勿转载,TKS!

「NOIP2016」换教室的更多相关文章

  1. LOJ2360. 「NOIP2016」换教室【概率DP】【Floyed】【傻逼题】

    LINK 思路 先floyed出两点最短路 然后就可以直接\(dp_{i,j,0/1}\)表示前i节课选择换j节,换不换当前这一节的最小贡献 直接可以枚举上一次决策的状态计算概率进行统计就可以了 我变 ...

  2. [LOJ] #2360. 「NOIP2016」换教室

    期望DP #include<iostream> #include<cstring> #include<cstdio> #include<cctype> ...

  3. 「NOIP2016」「P1850」 换教室(期望dp

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

  4. LOJ #2359. 「NOIP2016」天天爱跑步(倍增+线段树合并)

    题意 LOJ #2359. 「NOIP2016」天天爱跑步 题解 考虑把一个玩家的路径 \((x, y)\) 拆成两条,一条是 \(x\) 到 \(lca\) ( \(x, y\) 最近公共祖先) 的 ...

  5. 「NOIP2016」天天爱跑步 题解

    (声明:图片来源于网络) 「NOIP2016」天天爱跑步 题解 题目TP门 题目 题目描述 小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.<天天爱跑步>是 ...

  6. 「 Luogu P1850 」 换教室

    解题思路 很明显的是个期望 $dp$. 先前想到 $dp[i][j]$ 表示第决策到第 $i$ 个时间段,已经进行了 $j$ 次申请,然后就没有然后了,因为这根本就没法转移啊,你又不知道前 $i-1$ ...

  7. [NOIP2016][luogu]换教室[DP]

    [NOIP2016] Day1 T3 换教室 ——!x^n+y^n=z^n 题目描述 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程. 在可以选择的课程中,有 2n 节课程 ...

  8. 【BZOJ4720】【NOIP2016】换教室 [期望DP]

    换教室 Time Limit: 20 Sec  Memory Limit: 512 MB[Submit][Status][Discuss] Description Input 第一行四个整数n,m,v ...

  9. 【NOIP2016】换教室 题解(期望DP)

    前言:状态贼鸡儿多,眼睛快瞎了. ----------------------- 题目链接 题目大意:给定$n(课程数),m(可换次数),v(教室数),e(无向边数)$,同时给定原定教室$c[i]$和 ...

随机推荐

  1. 像Java一样管理对象:T&形式仅仅用在参数传递

    类的对象为了关联/包含一个T类型的instance,若成员变量包括T*/ T&, 这种设计叫做“aggregation”(聚合):而若采用T 形式,则称为"composition&q ...

  2. Elasticsearch DSL 常用语法介绍

    课程环境 CentOS 7.3 x64 JDK 版本:1.8(最低要求),主推:JDK 1.8.0_121 Elasticsearch 版本:5.2.0 相关软件包百度云下载地址(密码:0yzd):h ...

  3. tensorflow中使用变量作用域及tf.variable(),tf,getvariable()与tf.variable_scope()的用法

    一 .tf.variable() 在模型中每次调用都会重建变量,使其存储相同变量而消耗内存,如: def repeat_value(): weight=tf.variable(tf.random_no ...

  4. IDEA 环境下更改Maven的仓库镜像提高下载速度

    Maven把所有常用的jar包存放在一个集中的仓库(repository)中,项目需要什么jar包和他相关的依赖,只要在pom.xml文件中声明就可了,还是很方便的.repository分两种,一个是 ...

  5. windows查看某个端口被哪个进程占用

    找出端口对应的PID netstat -ano | findstr 8080 帮助命令netstat -? -a 显示所有连接和侦听端口. -n 以数字形式显示地址和端口号. -o 显示拥有的与每个连 ...

  6. IDEA新建一个Spring Boot项目

    Maven构建项目模板 maven构建的是maven风格的纯净模板,要转变成spring boot项目需要自己添加依赖等配置. mvn archetype:generate: Maven插件原型是一个 ...

  7. 鼠标按下改变RelativeLayout背景颜色,松开变回

    在drawable下创建bg.xml文件 <?xml version="1.0" encoding="utf-8"?> <selector x ...

  8. js 对象克隆方法总结(不改变原对象)

    1.通用对象克隆: function clone(obj){ let temp = null; if(obj instanceof Array){ temp = obj.concat(); }else ...

  9. ionic创建组件、页面或者过滤器

    ionic可以直接 用命令来创建组件.页面或者过滤器. 在ionic项目根目录打开命令窗口.输入下列命令: ionic g page pageName //创建新页面 ionic g componen ...

  10. Ingress使用示例

    Ingress概念介绍 service只能做四层代理 无法做七层代理(如https服务)      lvs只能根据第四层的数据进行转发 无法对七层协议数据进行调度 Ingress Controller ...