zoukankan      html  css  js  c++  java
  • BZOJ P4720[Noip2016]换教室____solution

    题目太长不表

           <--无形传送,最为致命



    学习一点数学期望的基础,预处理最短路,然后加上DP即可。(废话)

    理解决策和结果的差别:

    在这里每阶段的决策有两个:申请|不申请

    结果有两个:换|不换

    然而二者不是一一对应的关系;

    而且决策意味着状态,结果只用于计算期望

    为什么呢

    因为答案要的就是对于某种决策组的期望

    于是状态的设计应该是分为申请|不申请,

    然后计算期望时讨论申请成不成功;

    状态:f[i,j,0/1]讨论前i节课,申请j次,第三维=[第i节申请了]  

    方程:

    //f[i][j][0]=f[i-1][j][0]+dis(ci-1,ci)*ff[i-1][j][0]|f[i-1][j][1]+dis(ci-1,ci)*ff[i-1][j][1]+dis(di-1,ci)*ff[i-1][j][2]
    //f[i][j][1]=f[i-1][j-1][0]+(dis(ci-1,di)*ki+dis[ci-1,ci]*(1-ki))*ff[i-1][j-1][0]|f[i-1][j-1][1]+(dis(ci-1,di)*ki+dis(ci-1,ci)*(1-ki))*ff[i-1][j-1][1]+(dis(di-1,di)*ki+dis(di-1,ci)*(1-ki))*ff[i-1][j-1][2]

    |表示两者选一(当然是选小的)

    ff表示与f(也就是期望)同步存在的概率

    dis是最短路

    剩下的如题

    对了最短路记得判重边。

    代码:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cmath>
     4 using namespace std;
     5 double f[2010][2010][2];
     6 double ff[2010][2010][3];
     7 int dis[310][310];
     8 int c[2010],d[2010];
     9 double ki[2010];
    10 int n,m,v,e;
    11 int main()
    12 {
    13     int i,j,k,l;
    14     double min=2147483600;
    15     memset(dis,0x3f3f3f,sizeof(dis));
    16     scanf("%d%d%d%d",&n,&m,&v,&e);
    17     for(i=1;i<=n;i++)scanf("%d",&c[i]);
    18     for(i=1;i<=n;i++)scanf("%d",&d[i]);
    19     for(i=1;i<=n;i++)scanf("%lf",&ki[i]);
    20     for(i=1;i<=e;i++){
    21         scanf("%d%d%d",&j,&k,&l);
    22         if(l<dis[j][k])
    23             dis[j][k]=dis[k][j]=l;
    24     }
    25     for(k=1;k<=v;k++)
    26         for(i=1;i<=v;i++)
    27             for(j=1;j<=v;j++)
    28                 if(i!=j)
    29                     if (dis[i][j]>dis[i][k]+dis[k][j])
    30                         dis[i][j]=dis[i][k]+dis[k][j];
    31     for(i=1;i<=v;i++)dis[i][i]=0;
    32     for(i=0;i<=n;i++)
    33         for(j=0;j<=m;j++)
    34             f[i][j][0]=f[i][j][1]=2147483600,ff[i][j][0]=ff[i][j][1]=ff[i][j][2]=2;
    35     ff[1][1][1]=1-ki[1];ff[1][1][2]=ki[1];ff[1][0][0]=1;
    36     f[1][1][1]=0;f[1][0][0]=0;
    37     for(i=2;i<=n;i++)
    38         for(j=0;j<=m;j++){
    39             if(f[i-1][j][0]+dis[c[i-1]][c[i]]*ff[i-1][j][0]<f[i-1][j][1]+dis[c[i-1]][c[i]]*ff[i-1][j][1]+dis[d[i-1]][c[i]]*ff[i-1][j][2])
    40                 f[i][j][0]=f[i-1][j][0]+dis[c[i-1]][c[i]]*ff[i-1][j][0],ff[i][j][0]=ff[i-1][j][0];
    41             else
    42                 f[i][j][0]=f[i-1][j][1]+dis[c[i-1]][c[i]]*ff[i-1][j][1]+dis[d[i-1]][c[i]]*ff[i-1][j][2],ff[i][j][0]=ff[i-1][j][1]+ff[i-1][j][2];
    43             if(j>0){
    44                 if(f[i-1][j-1][0]+(dis[c[i-1]][d[i]]*ki[i]+dis[c[i-1]][c[i]]*(1-ki[i]))*ff[i-1][j-1][0]<f[i-1][j-1][1]+(dis[c[i-1]][d[i]]*ki[i]+dis[c[i-1]][c[i]]*(1-ki[i]))*ff[i-1][j-1][1]+(dis[d[i-1]][d[i]]*ki[i]+dis[d[i-1]][c[i]]*(1-ki[i]))*ff[i-1][j-1][2])
    45                     f[i][j][1]=f[i-1][j-1][0]+(dis[c[i-1]][d[i]]*ki[i]+dis[c[i-1]][c[i]]*(1-ki[i]))*ff[i-1][j-1][0],ff[i][j][1]=ff[i-1][j-1][0]*(1-ki[i]),ff[i][j][2]=ff[i-1][j-1][0]*ki[i];
    46                 else
    47                     f[i][j][1]=f[i-1][j-1][1]+(dis[c[i-1]][d[i]]*ki[i]+dis[c[i-1]][c[i]]*(1-ki[i]))*ff[i-1][j-1][1]+(dis[d[i-1]][d[i]]*ki[i]+dis[d[i-1]][c[i]]*(1-ki[i]))*ff[i-1][j-1][2],ff[i][j][1]=(ff[i-1][j-1][1]+ff[i-1][j-1][2])*(1-ki[i]),ff[i][j][2]=(ff[i-1][j-1][1]+ff[i-1][j-1][2])*ki[i];
    48             }
    49         }
    50     for(i=0;i<=m;i++){
    51         if(min>f[n][i][0])min=f[n][i][0];
    52         if(min>f[n][i][1])min=f[n][i][1];
    53     }
    54     printf("%.2lf",min);
    55     return 0;
    56 }

    现在想来,我还真是弱啊

  • 相关阅读:
    C++学习笔记32:泛型编程拓展1
    C++学习笔记31:术语翻译
    Sqrt(x)
    Search a 2D Matrix
    Pascal's Triangle II
    Pascal's Triangle
    Climbing Stairs
    Linux实用命令
    Binary Tree Inorder Traversal
    Minimum Depth of Binary Tree
  • 原文地址:https://www.cnblogs.com/nietzsche-oier/p/7372005.html
Copyright © 2011-2022 走看看