zoukankan      html  css  js  c++  java
  • [NOIP 2016] 换教室

    嘟嘟嘟

    这道题很显然是dp,刚开始我是设dp[i][j]表示到第 i 个时间段,申请了 j 个课程耗费的体力值的总和的最小期望值,但是想了半天也没有推出转移方程,现在想想觉得应该是无法表示他第 i 时刻在哪一个教室。

    于是我们加一维dp[i][j][0/1]表示第 i 时刻我们是否申请了换教室。那么dp方程就很好推出来了:

    先令u1 = c[i - 1], v1 = c[i], u2 = d[i - 1], v2 = d[i]

    dp[i][j][0] = min(dp[i - 1][j][0] + v[u1][v1], dp[i - 1][j][1] + v[u2][v1] * k[i - 1] + v[u1][v1] * (1 - k[i - 1]))

    dp[i][j][1] = min(dp[i - 1][j - 1][0] + v[u1][v2] * k[i] + v[u1][v1] * (1 - k[i]),

           dp[i - 1][j - 1][1] + v[u2][v2] * k[i - 1] * k[i] + v[u1][v2] * (1 - k[i - 1]) * k[i] + v[u2][v1] * k[i - 1] * (1 - k[i]) + v[u1][v1] * (1 - k[i - 1]) * (1 - k[i]))

    总的来说,就是如果这一次申请换教室的话,要同时考虑换教室成功和不成功的两种情况。

    然后ans = min(dp[n][i][0], dp[n][i][1]) (0 <= i <= m,因为可以不申请换任何一个教室)

    然后求多源最短路,又因为V <= 300,直接floyd预处理就行。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<cstdlib>
     7 #include<cctype>
     8 #include<vector>
     9 #include<stack>
    10 #include<queue>
    11 using namespace std;
    12 #define enter puts("") 
    13 #define space putchar(' ')
    14 #define Mem(a) memset(a, 0, sizeof(a))
    15 typedef long long ll;
    16 typedef double db;
    17 const int INF = 0x3f3f3f3f;
    18 const db eps = 1e-8;
    19 const int max_nod = 305;
    20 const int maxn = 2e3 + 5;
    21 inline ll read()
    22 {
    23     ll ans = 0;
    24     char ch = getchar(), last = ' ';
    25     while(!isdigit(ch)) {last = ch; ch = getchar();}
    26     while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();}
    27     if(last == '-') ans = -ans;
    28     return ans;
    29 }
    30 inline void write(ll x)
    31 {
    32     if(x < 0) x = -x, putchar('-');
    33     if(x >= 10) write(x / 10);
    34     putchar(x % 10 + '0');
    35 }
    36 
    37 int n, m, V, E;
    38 ll v[max_nod][max_nod]; 
    39 int a[maxn], b[maxn];
    40 db p[maxn];
    41 db dp[maxn][maxn][2];
    42 
    43 void init()
    44 {
    45     for(int i = 1; i <= V; ++i)
    46         for(int j = 1; j <= V; ++j) v[i][j] = INF;
    47     for(int i = 1; i <= n; ++i)
    48         for(int j = 0; j <= m; ++j) dp[i][j][0] = dp[i][j][1] = INF;        //j:0开始 
    49 }
    50 
    51 int main()
    52 {
    53     n = read(); m = read(); V = read(); E = read();
    54     for(int i = 1; i <= n; ++i) a[i] = read();
    55     for(int i = 1; i <= n; ++i) b[i] = read();
    56     for(int i = 1; i <= n; ++i) scanf("%lf", &p[i]);
    57     init();
    58     for(int i = 1; i <= E; ++i)
    59     {
    60         int x = read(), y = read(); ll co = read();
    61         v[x][y] = v[y][x] = min(v[x][y], co);
    62     }
    63     for(int k = 1; k <= V; ++k)
    64         for(int i = 1; i <= V; ++i)
    65             for(int j = 1; j <= V; ++j)
    66                 v[i][j] = min(v[i][j], v[i][k] + v[k][j]);
    67     for(int i = 1; i <= V; ++i) v[i][i] = v[i][0] = v[0][i] = 0;
    68     dp[1][0][0] = dp[1][1][1] = 0;
    69     for(int i = 2; i <= n; ++i)
    70     {
    71         dp[i][0][0] = dp[i - 1][0][0] + v[a[i - 1]][a[i]];
    72         for(int j = 1; j <= min(i, m); ++j)
    73         {
    74             db tp_0 = dp[i - 1][j][0] + v[a[i - 1]][a[i]];
    75             db tp_1 = dp[i - 1][j][1] + (db)v[b[i - 1]][a[i]] * p[i - 1] + (db)v[a[i - 1]][a[i]] * (1 - p[i - 1]);
    76             dp[i][j][0] = min(dp[i][j][0], min(tp_0, tp_1));
    77             tp_0 = dp[i - 1][j - 1][0] + (db)v[a[i - 1]][b[i]] * p[i] + (db)v[a[i - 1]][a[i]] * (1 - p[i]);
    78             tp_1 = dp[i - 1][j - 1][1] + (db)v[b[i - 1]][b[i]] * p[i - 1] * p[i] + (db)v[a[i - 1]][b[i]] * (1 - p[i - 1]) * p[i];
    79             tp_1 += (db)v[b[i - 1]][a[i]] * p[i - 1] * (1 - p[i]) + (db)v[a[i - 1]][a[i]] * (1 - p[i - 1]) * (1 - p[i]);
    80             dp[i][j][1] = min(dp[i][j][1], min(tp_0, tp_1));
    81         }
    82     }
    83     db ans = INF;
    84     for(int i = 0; i <= m; ++i) ans = min(ans, min(dp[n][i][0], dp[n][i][1]));
    85     printf("%.2lf
    ", ans);
    86     return 0;
    87 }
    View Code
  • 相关阅读:
    Math 和 Date
    GRID布局
    移动端项目布局类型
    媒体查询 + rem用法
    字符串
    ES5 中常见的数组常用方法
    数组的排序
    毕设制作:前端界面 2020-02-01
    阅读笔记十六——排序算法
    阅读笔记十五——阿里面试题
  • 原文地址:https://www.cnblogs.com/mrclr/p/9634750.html
Copyright © 2011-2022 走看看