• luogu1850 NOIP2016 换教室


    题目

    注:以上图片截图自洛谷

    分析

     这道题概率DP,前置知识:数学期望

    part 1 状态

    dp [ 第 i 个时间段 ] [ 换了 j 次 ] [ 当前是否换了 ] = 最优方案的期望值

    part 2 转移

    我们把期望下放到每条路;

    你可以选择申请或不申请;

    如果选择申请:期望的路径长 = (申请成功的路径长) * 申请成功概率 + (申请不成功的路径长) * 申请不成功概率

    这里注意不要被样例解释误导了,推导一下他们其实是一样的,因为我们的状态是:dp [ 第 i 个时间段 ] [ 换了 j 次 ] [ 当前是否换了 ] = 最优方案的期望值

    代码

      1 /*************************
      2 User:Mandy.H.Y
      3 Language:c++
      4 Problem:luogu1850
      5 Algorithm: 
      6 *************************/
      7 
      8 #include<bits/stdc++.h>
      9 
     10 using namespace std;
     11 
     12 const int maxn = 2005;
     13 const int maxv = 305;
     14 const int maxe = 90005;
     15 
     16 int n,m,v,e,size;
     17 int c[maxn],d[maxn];
     18 double k[maxn],dp[maxn][maxn][3];
     19 int g[maxv][maxv];
     20 
     21 struct Edge{
     22     int v,nt,w;
     23 }edge[maxe << 1];
     24 
     25 template<class T>inline void read(T &x){
     26     x = 0;bool flag = 0;char ch = getchar();
     27     while(!isdigit(ch)) flag |= ch == '-',ch = getchar();
     28     while(isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48),ch = getchar();
     29     if(flag) x = -x;
     30 }
     31 
     32 template<class T>void putch(const T x){
     33     if(x > 9) putch(x / 10);
     34     putchar(x % 10 | 48);
     35 }
     36 
     37 template<class T>void put(const T x){
     38     if(x < 0) putchar('-'),putch(-x);
     39     else putch(x);
     40 }
     41 
     42 void file(){
     43     freopen("1850.in","r",stdin);
     44     freopen("1850.out","w",stdout);
     45 }
     46 
     47 void readdata(){
     48     memset(g,0x3f3f3f3f,sizeof(g));
     49     read(n);read(m);read(v);read(e);
     50     for(int i = 1;i <= v; ++ i) g[i][i] = 0;
     51     for(int i = 1;i <= n; ++ i) read(c[i]);
     52     for(int i = 1;i <= n; ++ i) read(d[i]);
     53     for(int i = 1;i <= n; ++ i) scanf("%lf",&k[i]);
     54     for(int i = 1;i <= e; ++ i) {
     55         int u,v,w;
     56         read(u);read(v);read(w);
     57         g[u][v] = min(g[u][v],w);
     58         g[v][u] = g[u][v];
     59     }
     60 }
     61 
     62 void Floyd(){
     63     for(int l = 1;l <= v; ++ l)
     64     for(int i = 1;i <= v; ++ i)
     65     for(int j = 1;j <= v; ++ j){
     66         if(g[i][l] != 0x3f3f3f3f && g[l][j] != 0x3f3f3f3f)
     67             if(g[i][l] + g[l][j] < g[i][j]) g[i][j] = g[i][l] + g[l][j];
     68     }
     69 }
     70 
     71 void work(){
     72     
     73     Floyd();
     74     
     75     for(int i = 2;i <= n; ++ i){
     76         
     77         int u1 = c[i - 1],u2 = d[i - 1];
     78         int v1 = c[i],v2 = d[i];
     79         
     80         dp[i][0][0] = dp[i - 1][0][0] + g[u1][v1];
     81         
     82         for(int j = 1;j <= m; ++ j){
     83             
     84             dp[i][j][0] = min(dp[i - 1][j][0] + g[u1][v1],
     85                               dp[i - 1][j][1] + 
     86                               k[i - 1] * g[u2][v1] + 
     87                               (1 - k[i - 1]) * g[u1][v1]);
     88             
     89             dp[i][j][1] = dp[i - 1][j - 1][0] + 
     90                           k[i] * g[u1][v2] + 
     91                           (1 - k[i]) * g[u1][v1];
     92             if(j > 1) dp[i][j][1] = min(dp[i][j][1],dp[i - 1][j - 1][1] + 
     93                                                     k[i - 1] * k[i] * g[u2][v2] + 
     94                                                     k[i - 1] * (1 - k[i]) * g[u2][v1] +
     95                                                     (1 - k[i - 1]) * k[i] * g[u1][v2] +
     96                                                     (1 - k[i - 1]) * (1 - k[i]) * g[u1][v1]);
     97         
     98         }
     99     }
    100     double ans = 2000000000.0;
    101     for(int i = 0;i <= m; ++ i) {
    102         ans = min(ans,dp[n][i][0]);
    103         if(i > 0) ans = min(ans,dp[n][i][1]);
    104     }
    105     
    106     printf("%.2lf",ans);
    107 }
    108 
    109 int main(){
    110 //    file();
    111     readdata();
    112     work();
    113     return 0;
    114 }
    View Code
    非做顽石不可,哪管他敬仰暗唾
  • 相关阅读:
    Open_basedir 开启后项目变慢
    PHP导入百万级excel数据方案
    使用Python统计项目代码行数(Python3.X)
    AttributeError: '_io.TextIOWrapper' object has no attribute 'xreadlines'
    startTime = time.clock()AttributeError: module 'time' has no attribute 'clock
    SyntaxError: Missing parentheses in call to 'print'. Did you mean print
    误删 Win10 应用商店应该如何恢复?
    win10无法开启Windows Defender Firewall服务,错误1058
    设备管理器里面的AAP Server是什么?
    layui——Cannot create property 'LAY_TABLE_INDEX' on number '2'
  • 原文地址:https://www.cnblogs.com/Mandy-H-Y/p/11402121.html
Copyright © 2020-2023  润新知