zoukankan      html  css  js  c++  java
  • [NOIP2016]换教室 BZOJ 4720

         这道题应该是一个概率dp

         首先先用floyd跑一遍处理处最短路,其中两点需要注意

               1、dis[i][i]要初始化为零

                2、注意有重边!!!!

        之后就开始dp转移,用f[i][j][k] 来表示状态,i 表示是i 时刻;j表示还剩下多少可以换教室的机会;当k=0表示在i时间点,剩下j的机会的情况下,不换教室,k=1表示换教室;

       所以f[i][j][0]=min(f[i-1][j][0]+dis[beg[i-1]][beg[i]],f[i-1][j][1]+dis[beg[i-1]][beg[i]]*(1-p[i-1])+dis[ano[i-1]][beg[i]]*p[i]),其中p[i]是i时刻换教室的成功概率,beg[i]是初始教室,ano[i]是可换的教室;

       f[i][j-1][0]=min(f[i-1][j][0]+(double)dis[beg[i-1]][beg[i]]*(1-p[i])+(double)dis[beg[i-1]][ano[i]]*p[i],

    f[i-1][j][1]+(double)dis[beg[i-1]][beg[i]]*(1-p[i-1])*(1-p[i])+(double)dis[beg[i-1]][ano[i]]
    *(1-p[i-1])*p[i]+(double)dis[ano[i-1]][beg[i]]*p[i-1]*(1-p[i])
    +(double)dis[ano[i-1]][ano[i]]*p[i-1]*p[i])
    转移方程有点长的,但总之就是在四个可行的道路之间选择,并乘上概率,就这么一直转移到n即可,在for循环找一遍答案就行了         
     1 #include<cmath>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<cstring>
     5 #include<iostream>
     6 #include<algorithm>
     7 using namespace std;
     8 int n,m,dian_shu,bian_shu;
     9 int beg[2010],ano[2010];
    10 double p[2010];
    11 int dis[310][310];
    12 double f[2010][2010][3];
    13 void ot(){
    14     for(int i=1;i<=n;i++){
    15         for(int j=0;j<=m;j++){
    16             cout<<"ij= "<<i<<"  "<<j<<endl;
    17             cout<<f[i][j][0]<<"   "<<f[i][j][1]<<endl;
    18         }
    19     }
    20 }
    21 void ot2(){
    22     for(int i=0;i<=m;i++){
    23         cout<<"i== "<<i<<endl;
    24         cout<<"-- "<<f[2][i][0]<<"  "<<f[2][i][1]<<endl;
    25     }
    26 }
    27 void init(){
    28     for(int i=1;i<=n;i++) scanf("%d",&beg[i]);
    29     for(int i=1;i<=n;i++) scanf("%d",&ano[i]);
    30     for(int i=1;i<=n;i++) scanf("%lf",&p[i]);
    31     int x,y,z;
    32     memset(dis,30,sizeof(dis));
    33     for(int i=1;i<=dian_shu;i++)
    34         dis[i][i]=0;
    35     for(int i=1;i<=bian_shu;i++){
    36         scanf("%d%d%d",&x,&y,&z);
    37         dis[x][y]=min(dis[x][y],z); dis[y][x]=min(dis[y][x],z);
    38     }
    39     for(int k=1;k<=dian_shu;k++){
    40         for(int i=1;i<=dian_shu;i++){
    41             for(int j=1;j<=dian_shu;j++){
    42                 dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
    43             }
    44         }
    45     }
    46 }
    47 void Dp(){
    48     for(int i=1;i<=n;i++){
    49         for(int j=0;j<=m;j++){
    50             f[i][j][1]=f[i][j][0]=200000000.0;
    51         }
    52     }
    53     f[1][m][0]=0;
    54     f[1][m-1][1]=0;
    55     for(int i=2;i<=n;i++){
    56         for(int j=m;j>=0;j--){
    57             f[i][j][0]=min( f[i-1][j][0] + (double)dis[beg[i-1]][beg[i]] ,f[i-1][j][1] + (double)(1-p[i-1])*dis[beg[i-1]][beg[i]] + (double)p[i-1]*dis[ano[i-1]][beg[i]]);
    58             if(j==0) continue;
    59             double aa=f[i-1][j][0]+(double)dis[beg[i-1]][beg[i]]*(1-p[i])+(double)dis[beg[i-1]][ano[i]]*p[i];
    60             double bb=f[i-1][j][1]+(double)dis[beg[i-1]][beg[i]]*(1-p[i-1])*(1-p[i])+(double)dis[beg[i-1]][ano[i]]*(1-p[i-1])*p[i]
    61                       +(double)dis[ano[i-1]][beg[i]]*p[i-1]*(1-p[i])+(double)dis[ano[i-1]][ano[i]]*p[i-1]*p[i];
    62             /*if(i==2 && j==1){
    63                 cout<<(double)dis[ano[i-1]][ano[i]]*p[i-1]*p[i]<<endl;
    64                 cout<<"-->   "<<aa<<"  "<<bb<<endl;
    65             }*/
    66             f[i][j-1][1]=min(aa,bb);
    67         }
    68     }
    69 }
    70 int main(){
    71     //freopen("classrooma.in","r",stdin);
    72     //freopen("classrooma.out","w",stdout);
    73     scanf("%d%d%d%d",&n,&m,&dian_shu,&bian_shu);
    74     init();
    75     Dp();
    76     double ans=200000000.0;
    77     for(int i=0;i<=m;i++){
    78         ans=min(ans,f[n][i][0]);
    79         ans=min(ans,f[n][i][1]);
    80     }
    81     //ot();
    82 //  ot2();
    83 /*
    84     int sc=0;
    85     cout<<"st"<<endl;
    86     for(int i=2;i<=n;i++){
    87         sc+=dis[beg[i-1]][beg[i]];
    88         cout<<dis[beg[i-1]][beg[i]]<<endl;
    89     }
    90     cout<<"sc== "<<sc<<endl;*/
    91     printf("%.2lf",ans);
    92     return 0;
    93  
    94 }
    95 /**********************************************
  • 相关阅读:
    钱途第三章(不同类别的风险投资)
    羊皮卷之九
    MAP平台界面公式的 package 包名自定义
    java类Timer和TimerTask的使用
    钱途第五章(创业初期的公司安排)
    MYSQL 双向同步方案:
    羊皮卷之六
    羊皮卷之十
    羊皮卷之一
    MAP平台自定义查询
  • 原文地址:https://www.cnblogs.com/FOXYY/p/7236732.html
Copyright © 2011-2022 走看看