zoukankan      html  css  js  c++  java
  • 洛谷P1850 换教室

    令人印象深刻的状态转移方程...

    f[i][j][0/1]表示前i个换j次,第i次是否申请时的期望。

    注意可能有重边,自环。

    转移要分类讨论,距离是上/这次成功/失败的概率乘相应的路程。

    从上次的0/1中取min

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 const int N = 310, M = 2010;
     5 const double INF = 1.0 * 0x3f3f3f3f;
     6 
     7 inline void read(int &x) {
     8     x = 0;
     9     char c = getchar();
    10     while(c > '9' || c < '0') {
    11         c = getchar();
    12     }
    13     while(c >= '0' && c <= '9') {
    14         x = (x << 1) + (x << 3) + c - 48;
    15         c = getchar();
    16     }
    17     return;
    18 }
    19 
    20 int G[N][N], a[M], b[M];
    21 double k[M], f[M][M][2];
    22 
    23 int main() {
    24     int n, m, v, e;
    25     read(n);
    26     read(m);
    27     read(v);
    28     read(e);
    29     for(int i = 1; i <= n; i++) {
    30         read(a[i]);
    31     }
    32     for(int i = 1; i <= n; i++) {
    33         read(b[i]);
    34     }
    35     for(int i = 1; i <= n; i++) {
    36         scanf("%lf", &k[i]);
    37     }
    38     int x, y, z;
    39     memset(G, 0x3f, sizeof(G));
    40     for(int i = 1; i <= e; i++) {
    41         read(x);
    42         read(y);
    43         read(z);
    44         if(G[x][y]) {
    45             G[y][x] = G[x][y] = std::min(G[x][y], z);
    46         }
    47         else {
    48             G[x][y] = G[y][x] = z;
    49         }
    50     }
    51 
    52     /// floyd
    53     for(int i = 1; i <= v; i++) {
    54         G[i][i] = 0;
    55     }
    56     for(int p = 1; p <= v; p++) {
    57         for(int i = 1; i <= v; i++) {
    58             for(int j = 1; j <= v; j++) {
    59                 G[i][j] = std::min(G[i][j], G[i][p] + G[p][j]);
    60             }
    61         }
    62     }
    63 
    64     for(int i = 1; i <= n; i++) {
    65         for(int j = 0; j <= m; j++) {
    66             f[i][j][0] = f[i][j][1] = INF;
    67         }
    68     }
    69     f[1][0][0] = f[1][1][1] = 0;
    70     for(int i = 2; i <= n; i++) {
    71         for(int j = 0; j <= m; j++) {
    72             f[i][j][0] = std::min(f[i - 1][j][0] + G[a[i - 1]][a[i]],
    73                                   f[i - 1][j][1]
    74                                   + G[b[i - 1]][a[i]] * k[i - 1]
    75                                   + G[a[i - 1]][a[i]] * (1 - k[i - 1]));
    76             if(j) {
    77                 f[i][j][1] = std::min(f[i - 1][j - 1][0]
    78                                       + G[a[i - 1]][b[i]] * k[i]
    79                                       + G[a[i - 1]][a[i]] * (1 - k[i]),
    80                                       f[i - 1][j - 1][1]
    81                                       + G[b[i - 1]][b[i]] * k[i - 1] * k[i]
    82                                       + G[b[i - 1]][a[i]] * k[i - 1] * (1 - k[i])
    83                                       + G[a[i - 1]][b[i]] * (1 - k[i - 1]) * k[i]
    84                                       + G[a[i - 1]][a[i]] * (1 - k[i - 1]) * (1 - k[i]));
    85             }
    86         }
    87     }
    88 
    89     double ans = INF;
    90 
    91     for(int i = 0; i <= m; i++) {
    92         ans = std::min(ans, f[n][i][0]);
    93         ans = std::min(ans, f[n][i][1]);
    94     }
    95     printf("%.2lf", ans);
    96 
    97     return 0;
    98 }
    AC代码

    我一开始把ans初值设的是0...

  • 相关阅读:
    如何找回Oracle所有用户丢失的密码
    数据库范式详解
    lua
    cdn
    初心
    广州
    vim 命令
    git 命令
    Linux琐碎
    汪国真语录
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/9665136.html
Copyright © 2011-2022 走看看