[NOIP2016] Day1 T3 换教室

——!x^n+y^n=z^n

题目描述

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

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

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

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

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

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

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

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

输入输出格式

输入格式:

  第一行四个整数 n,m,v,e。n 表示这个学期内的时间段的数量;m 表示牛牛最多可以申请更换多少节课程的教室;v 表示牛牛学校里教室的数量;e表示牛牛的学校里道路的数量。

  第二行 n 个正整数,第 i(1≤i≤n)个正整数表示 ci​,即第 i 个时间段牛牛被安排上课的教室;保证 1≤ci​≤v。

  第三行 n 个正整数,第 i(1 \leq i \leq n1≤i≤n)个正整数表示 di​,即第 ii 个时间段另一间上同样课程的教室;保证1≤di​≤v。

  第四行 n 个实数,第 i(1≤i≤n)个实数表示 ki​,即牛牛申请在第 ii 个时间段更换教室获得通过的概率。保证0≤ki​≤1。

  接下来 e 行,每行三个正整数 aj​,bj​,wj​,表示有一条双向道路连接教室aj​,bj​,通过这条道路需要耗费的体力值是wj​;保证1≤aj​,bj​≤v,1≤wj​≤100。

  保证1≤n≤2000,0≤m≤2000,1≤v≤300,0≤e≤90000。

  保证通过学校里的道路,从任何一间教室出发,都能到达其他所有的教室。

  保证输入的实数最多包含 33 位小数。

输出格式:

  输出一行,包含一个实数,四舍五入精确到小数点后恰好22位,表示答案。你的输出必须和标准输出完全一样才算正确。

  测试数据保证四舍五入后的答案和准确答案的差的绝对值不大于 4×10−3。
(如果你不知道什么是浮点误差,这段话可以理解为:对于大多数的算法,你可以正常地使用浮点数类型而不用对它进行特殊的处理)

输入输出样例:

输入样例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

输出样例1#

2.80


  首先,因为教室数量较少,我们可以先用floyd预处理出任意两个教室距离。

  注意到概率的相对独立,那么我们可以采用动态规划,用状态dp[i][j]表示上了前面i节课,用了j次申请的期望最优值,但这样会发现转移的时候出了问题,对于此用dp[i][j][0…1]表示状态,0表示该位置不申请,1表示申请。

  转移:

  dp[i][j][0]=Min{dp[i-1][j][0]+dis[s[i-1]][s[i]],//第i-1个也不取

        dp[i-1][j][1]+dis[t[i-1]][s[i]]*p[i-1]+dis[s[i-1]][s[i]]*(1-p[i-1])//第i-1个取,注意取与不取对应的概率都要计算

        };

  下面类似,只是有点恶心…

  dp[i][j][1]=Min{dp[i-1][j][0]+dis[s[i-1]][t[i]]*p[i]+dis[s[i-1]][s[i]]*(1-p[i]),

dp[i-1][j][1]+dis[s[i-1]][s[i]]*(1-p[i-1])*(1-p[i])+dis[s[i-1]][t[i]]*(1-p[i-1])*p[i]+

dis[t[i-1]][s[i]]*p[i-1]*(1-p[i])+dis[t[t-1]][t[i]]*p[i-1]*p[i]

          };

  总的方程转移还是比较好想的,只不过是概率期望比较坑,还有就是边界处理:

  dp[1][0][0]=dp[1][1][1]=0;

上代码...

 #include<iostream>
 #include<cstdio>
 #include<cstring>
 using namespace std;
 inline int read();
 int Min(int x,int y){return x<y?x:y;}
 ?y:x;}
 namespace lys{
      ;
      ;
     ],p[M];
     double ans;
     int n,m,v,e;
     int dis[M][M],s[M],t[M];
     void init(){
         int i,j;
         ;i<=v;i++)
             ;j<=v;j++){
                 if(i==j) continue ;
                 dis[i][j]=inf;
             }
         ;i<=n;i++)
             ;j<=m;j++) dp[i][j][]=dp[i][j][]=inf;
         dp[][][]=dp[][][]=;
     }
     int main(){
         int i,j,k,x,y,w;
         n=read(); m=read(); v=read(); e=read();
         ;i<=n;i++) s[i]=read();
         ;i<=n;i++) t[i]=read();
         ;i<=n;i++) scanf("%lf",&p[i]);
         init();
         ;i<=e;i++) x=read(),y=read(),w=read(),dis[x][y]=dis[y][x]=Min(dis[x][y],w);
         ;k<=v;k++)
             ;i<=v;i++)
                 ;j<=v;j++)
                     dis[i][j]=Min(dis[i][j],dis[i][k]+dis[k][j]);
         ;i<=n;i++){
             ;j<=m;j++){
                 dp[i][j][]=dp[i-][j][]+dis[s[i-]][s[i]];
                 dp[i][j][]=MIN(dp[i][j][],dp[i-][j][]+dis[t[i-]][s[i]]*p[i-]+dis[s[i-]][s[i]]*(-p[i-]));
                 ) dp[i][j][]=dp[i-][j-][]+dis[s[i-]][t[i]]*p[i]*(-p[i-])+dis[s[i-]][s[i]]*(-p[i])*(-p[i-])+dis[t[i-]][s[i]]*p[i-]*(-p[i])+dis[t[i-]][t[i]]*p[i-]*p[i];
                 ) dp[i][j][]=MIN(dp[i][j][],dp[i-][j-][]+dis[s[i-]][t[i]]*p[i]+dis[s[i-]][s[i]]*(-p[i]));
             }
         }
         ans=dp[n][][];
         ;i<=m;i++) ans=MIN(MIN(dp[n][i][],dp[n][i][]),ans);
         printf("%.2f",(ans));
         ;
     }
 }
 int main(){
     freopen("classroom.in","r",stdin);
     freopen("classroom.out","w",stdout);
     lys::main();
     fclose(stdin);
     fclose(stdout);
     ;
 }
 inline int read(){
     ,ff=;
     char c=getchar();
     '){
         ;
         c=getchar();
     }
     +c-',c=getchar();
     return kk*ff;
 }

[NOIP2016][luogu]换教室[DP]的更多相关文章

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

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

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

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

  3. P1850 换教室[dp+期望]

    流下了不会概率的眼泪,由于不会概率,转移少写了点东西... 这个dp很简单,就是一个普通的线性dp加点期望.(刚开始写这道题时信笔写下) \(dp[0/1][i][j]\)表示到第\(i\)个时间段时 ...

  4. [NOIP2016 D1T3]换教室 【floyd+概率dp】

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

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

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

  6. 【NOIP2016】换教室(DP,期望)

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

  7. 【NOIP2016】换教室(动态规划)

    题目戳我 题解 其实感觉16年的难度不是很大???? 这道题去年考场上DP都想出来了... 只是因为不会数学期望...然后GG.... 这道题目只要把数学期望搞出来就可以啦 设f[i][j][0/1] ...

  8. UOJ262 【NOIP2016】换教室

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转 ...

  9. 【NOIP2016】换教室

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

随机推荐

  1. 009-Spring Boot 事件监听、监听器配置与方式、spring、Spring boot内置事件

    一.概念 1.事件监听的流程 步骤一.自定义事件,一般是继承ApplicationEvent抽象类 步骤二.定义事件监听器,一般是实现ApplicationListener接口 步骤三.启动时,需要将 ...

  2. Linux_LDAP+NFS+autofs

    目录 目录 前言 Ldap LDAPNFSautofs ServerPost 前言 LDAP+NFS+Autofs也是一种网络用户集中管理解决方案,相对于NIS+NFS+Autofs而言,有着更可靠的 ...

  3. Pandas 50题练习

    f行的age改为1. df.loc['f', 'age'] = 1.5 这样比 df.loc['f']['age'] 好 计算df中每个种类animal的数量 df['animal'].value_c ...

  4. dvorak键盘布局调整

    一站直达: http://www.kaufmann.no/roland/dvorak/

  5. gdi+ 中发生一般性错误

    1.检查文件夹权限 2.保存的文件已存在并因某种原因被锁定. 3.文件夹路径不存在

  6. linux shell中的正则表达式

    正则表达式的使用 正则表达式,又称规则表达式.(英语:Regular Expression [ˈreɡjulə] 规则的 [ iksˈpreʃən] 表达 ),在代码中常简写为regex.regexp ...

  7. C与C#之间使用AES加密解密算法

    目的:C语言写的客户端加密数据,数据发送到C#写的服务端,服务端解密. 保证C与C#之间加密解密AES的配置和模式一直. AES: AES是对称加密算法,关键点: 密钥长度,明文长度,密文长度 密钥长 ...

  8. 大神级回答exists与in的区别

    google搜了一下,很多帖子,而且出发点不同,各有各的道理,但是有一个帖子讲的特别好: http://zhidao.baidu.com/question/134174568.html 忍不住在百度上 ...

  9. AppDomain (转)

    AppDomain是CLR的运行单元,它可以加载Assembly.创建对象以及执行程序.AppDomain是CLR实现代码隔离的基本机制. 每一个AppDomain可以单独运行.停止:每个AppDom ...

  10. 给当当同学的random data

    m**o 00'57"32街**o 00'52"23c**6 00'44"15斗**6 00'57"58n**5 00'32"04s**p 00'51 ...