题目

一道毒瘤概率期望DP。点这里

首先

对于每个时间段(就是每节课),我们有申请和不申请两种情况。如果不申请的话,一定在\(c[ i ]\),否则,可能在\(c[ i ]\),也可能在\(d[ i ]\)。所以我们先预处理一些东西。 先用弗洛伊德处理出最短路(这就不用详细介绍了吧)。我们先考虑相邻的两间教室,如果这两间教室都申请的话,就会有四种情况(①都通过,②都没通过,③第一个通过,④第二个通过)感觉又长又臭。所以我们先处理出两间教室都申请的情况。 用\(a[ i ]\)表示在都申请的前提下从第i个教室走到第i+1个教室的期望长度 \(dis[ i ] [ j ]\)表示从教室i到j的最短路。

情况①的概率为 $ k[ i ] k[ i+1 ] $ ,再乘上路径的长度 \(dis[ c[ i ] ][ c[ i+1 ] ]\)

同理 情况② \(1 - k[ i ]) (1 - k[ i+1 ]) dis[ d[ i ] ][ d[ i+1 ] ]\)

情况③ \(k[ i ] (1 - k[ i+1 ]) dis[ c[ i ] ][ d[ i+1 ] ]\)

情况④$(1 - k[ i ]) k[ i+1 ] * dis[ d[ i ] ][ c[ i+1 ] ] $

所以:

for(int i=1;i<=n;i++)
a[i]=(1-k[i])*(1-k[i+1])*dis[c[i]][c[i+1]]+
k[i]*(1-k[i+1])*dis[d[i]][c[i+1]]+k[i]*k[i+1]*dis[d[i]][d[i+1]]+
(1-k[i])*k[i+1]*dis[c[i]][d[i+1]]

太丑了

然后,继续预处理......

\(dp[ i ][ 0/1 ][ 0/1 ]\) 表示从第i节课的教室到第i+1节课的教室,第i节课的教室有(1)/没有(0)申请,第i+1个教室有(1)/没有(0)申请的期望长度

然后\(dp[ i ][ 1 ][ 1 ]\)的情况就是刚才的\(a[ i ]\)数组啦

其余情况同理可得,于是就:

for(int i=1;i<n;i++)
{
dp[i][0][0]=dis[c[i]][c[i+1]];
dp[i][1][1]=a[i];
dp[i][0][1]=k[i+1]*dis[c[i]][d[i+1]]+(1-k[i+1])*dis[c[i]][c[i+1]];
dp[i][1][0]=k[i]*dis[d[i]][c[i+1]]+(1-k[i])*dis[c[i]][c[i+1]];
}

然后,终于开始DP啦

用\(f[ i ][ j ][ 0/1 ]\) 示到达前i个教室,申请了j次,第i间教室有没有申请的期望最短长度。

!!!注意,j要从0开始,因为可以一次也不申请!!!

\(f[ i ][ j ][ 0 ]\)可以由\(f[ i - 1 ][ j ][ 0 ]\)和\(f[ i - 1 ][ j ][ 1 ]\)转移过来

\(f[ i ][ j ][ 1 ]\)可以由\(f[ i - 1][ j - 1 ][ 0 ]\)和\(f[ i - 1][ j - 1 ][ 1 ]\)转移过来

先初始化一下 \(f[ i ][ 0 ][ 0 ]\) 的情况

于是就得到了:

   f[1][1][1]=0; f[1][0][0]=0;
for(int i=2;i<=n;i++)
f[i][0][0]=f[i-1][0][0]+dis[c[i-1]][c[i]];
for(int i=2;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
f[i][j][0]=min(f[i-1][j][1]+dp[i-1][1][0],f[i-1][j][0]+dp[i-1][0][0]);
f[i][j][1]=min(f[i-1][j-1][1]+dp[i-1][1][1],f[i-1][j-1][0]+dp[i-1][0][1]);
}
}

最后统计答案就行啦,要注意可以申请 0到m次。


for(int i=1;i<=m;i++)
ans=min(ans,min(f[n][i][0],f[n][i][1]));

于是,这道题就做完了!

最后贴上完整版代码(大佬勿喷):


#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N = 2005;
const int INF = 27654134;
int n,m,v,e,c[N],d[N],dis[N][N];
double a[N],k[N],f[N][N][2],dp[N][2][2],ans=99999999.9;
//a[i]表示在都申请的前提下从第i个教室走到第i+1个教室的期望长度
// dp[i][0/1][0/1]从第i个教室到第i+1个教室,第i个教室有没有申请,第i+1个教室有没有申请的期望长度
//f[i][j][0/1]表示到达前i个教室,申请了j次,第i间教室有没有申请的期望最短长度
int main()
{
memset(f,0x7f,sizeof(f));
// memset(dis,0x7f,sizeof(dis));
scanf("%d%d%d%d",&n,&m,&v,&e);
for(int i=1;i<=v;i++)
for(int j=1;j<=v;j++)
dis[i][j]=INF;
for(int i=1;i<=n;i++) scanf("%d",&c[i]);
for(int i=1;i<=n;i++) scanf("%d",&d[i]);
for(int i=1;i<=n;i++) cin>>k[i];
int x,y,z;
for(int i=1;i<=e;i++)
{
scanf("%d%d%d",&x,&y,&z);
if(dis[x][y]) dis[x][y]=min(dis[x][y],z),dis[y][x]=min(dis[y][x],z);
else dis[x][y]=z,dis[y][x]=z;
}
for(int i=1;i<=v;i++) dis[i][i]=0;
for(int kk=1;kk<=v;kk++)
{
for(int i=1;i<=v;i++)
{
if(kk==i) continue;
for(int j=1;j<=v;j++)
{
if(kk==j||i==j) continue;
if(dis[i][kk]+dis[kk][j]<dis[i][j])
dis[i][j]=dis[i][kk]+dis[kk][j];
}
}
}
for(int i=1;i<=n;i++)
a[i]=(1-k[i])*(1-k[i+1])*dis[c[i]][c[i+1]]+
k[i]*(1-k[i+1])*dis[d[i]][c[i+1]]+k[i]*k[i+1]*dis[d[i]][d[i+1]]+
(1-k[i])*k[i+1]*dis[c[i]][d[i+1]];
for(int i=1;i<n;i++)
{
dp[i][0][0]=dis[c[i]][c[i+1]];
dp[i][1][1]=a[i];
dp[i][0][1]=k[i+1]*dis[c[i]][d[i+1]]+(1-k[i+1])*dis[c[i]][c[i+1]];
dp[i][1][0]=k[i]*dis[d[i]][c[i+1]]+(1-k[i])*dis[c[i]][c[i+1]];
}
f[1][1][1]=0; f[1][0][0]=0;
for(int i=2;i<=n;i++)
f[i][0][0]=f[i-1][0][0]+dis[c[i-1]][c[i]];
for(int i=2;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
f[i][j][0]=min(f[i-1][j][1]+dp[i-1][1][0],f[i-1][j][0]+dp[i-1][0][0]);
f[i][j][1]=min(f[i-1][j-1][1]+dp[i-1][1][1],f[i-1][j-1][0]+dp[i-1][0][1]);
}
}
for(int i=0;i<=m;i++)
ans=min(ans,min(f[n][i][0],f[n][i][1]));
printf("%.2lf\n",ans);
return 0;
}

NOIP2016换教室的更多相关文章

  1. [NOIP2016]换教室 D1 T3 Floyed+期望DP

    [NOIP2016]换教室 D1 T3 Description 对于刚上大学的牛牛来说, 他面临的第一个问题是如何根据实际情况中情合适的课程. 在可以选择的课程中,有2n节课程安排在n个时间段上.在第 ...

  2. BZOJ 4720 [Noip2016]换教室

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

  3. 【BZOJ】4720: [Noip2016]换教室

    4720: [Noip2016]换教室 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1690  Solved: 979[Submit][Status ...

  4. bzoj4720: [Noip2016]换教室(期望dp)

    4720: [Noip2016]换教室 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1294  Solved: 698[Submit][Status ...

  5. [NOIP2016]换教室 题解(奇怪的三种状态)

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

  6. 【bzoj4720】[NOIP2016]换教室

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

  7. [NOIp2016] 换教室

    题目类型:期望\(DP\) 传送门:>Here< 题意:现有\(N\)个时间段,每个时间段上一节课.如果不申请换教室,那么时间段\(i\)必须去教室\(c[i]\)上课,如果申请换课成功, ...

  8. [NOIP2016]换教室(概率期望$DP$)

    其实吧我老早就把这题切了--因为说实话,这道题确实不难啊--李云龙:比他娘的状压DP简单多了 今天我翻以前在Luogu上写的题解时,突然发现放错代码了,然后被一堆人\(hack\)--蓝瘦啊\(ORZ ...

  9. 【bzoj4720】[NOIP2016]换教室 期望dp

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

  10. NOIP2016换教室 BZOJ 4720

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

随机推荐

  1. CodeForces 461B Appleman and T

    题目链接:http://codeforces.com/contest/461/problem/B 题目大意: 给定一课树,树上的节点有黑的也有白的,有这样一种分割树的方案,分割后每个子图只含有一个黑色 ...

  2. Python中的 一些常用技巧函数[.join()]

    1.str.join(item)字符串操作函数,参数item可以是字符串.元组.字典,示例 ','.join('abc') [','.join('abc')] 输出: 'a,b,c'['a', 'b' ...

  3. Python——assert(断言函数)

    一.断言函数的作用 python assert断言是声明其布尔值必须为真的判定,如果发生异常就说明表达示为假.可以理解assert断言语句为raise-if-not,用来测试表示式,其返回值为假,就会 ...

  4. Centos7修改时区

    设置时区同样, 在 CentOS 7 中, 引入了一个叫 timedatectl 的设置设置程序. 用法很简单: # timedatectl # 查看系统时间方面的各种状态 Local time: 四 ...

  5. Qt 自定义按钮

    自定义控件的实现思路如下: a1.新建一个类,该类继承QPushbutton,由于QPushbutton继承于QWidget,因此可以直接在该继承类里面进行布局管理和挂载控件: a2.新建两个QLab ...

  6. 有关swiper动态改变数据遇到的坑(不能自动滚动,自动跟新数据,切换不正常)

    以前都觉得swiper的使用很简单,那是因为使用swiper时都是写的数据,按照官网上介绍直接初始化swiper,随便丢一个地方初始化就ok了,但是在很多需求中,我们都需要动态的改变数据,这样可能就会 ...

  7. Input标签使用整理

    0 写在前面 对于程序而言I/O是一个程序的重要组成部分.程序的输入.输出接口,指定了程序与用户之间的交互方式.对于前端开发而言,input标签也有着其重要地位,它为用户向服务端提交数据提供了可能. ...

  8. Kibana登录认证设置

    Kibana从5.5开始不提供认证功能,想用官方的认证,X-Pack,收费滴 . 所以就自己动手吧,用nginx的代理功能了. 1.安装Nginx: [root@ELK /]# yum -y inst ...

  9. ubuntu16.04+cuda9+cudnn7+tensorflow+pycharm环境搭建

    安装环境:ubuntu16.04+cuda9+cudnn7+tensorflow+pycharm 1)前期搭建过程主要是按照这篇博文,对于版本选择,安装步骤都讲得很详细,亲测有效! https://b ...

  10. pandas常用函数之diff

    diff函数是用来将数据进行某种移动之后与原数据进行比较得出的差异数据,举个例子,现在有一个DataFrame类型的数据df,如下: index value1 A 0 B 1 C 2 D 3 如果执行 ...