zoukankan      html  css  js  c++  java
  • 【NOIP2016】换教室 题解(期望DP)

    前言:状态贼鸡儿多,眼睛快瞎了。

    -----------------------

    题目链接

    题目大意:给定$n(课程数),m(可换次数),v(教室数),e(无向边数)$,同时给定原定教室$c[i]$和可换教室$d[i]$,换教室成功概率为$k[i]$,边权为$w[i]$。问耗费体力的最小期望值。

    -----------------

    设$f[i][j][0/1]$表示上完$i$节课,换教室$j$次后($0$表示此刻不换,$1$表示刺客换)的最小期望值。

    $C1=c[i-1],C2=c[i],C3=d[i-1],C4=d[i],mp[i][j]表示i到j的距离。$

    先考虑不换的情况:

    f[i][j][0]=min(f[i][j][0],min(f[i-1][j][0]+dis[c[i-1]][c[i]],f[i-1][j][1]+(1-k[i-1])*dis[c[i-1]][c[i]]+k[i-1]*dis[d[i-1]][c[i]]))

     

    考虑换的情况:

    f[i][j][1]=min(f[i][j][1],min(f[i-1][j-1][0]+dis[c[i-1]][c[i]]*(1-k[i])+dis[c[i-1]][d[i]]*k[i],f[i-1][j-1][1]+dis[d[i-1]][d[i]]*k[i-1]*k[i]+dis[d[i-1]][c[i]]*k[i-1]*(1-k[i])+dis[c[i-1]][c[i]]*(1-k[i-1])*(1-k[i])+dis[c[i-1]][d[i]]*(1-k[i-1])*k[i]))

     

    预处理最短路可以用$Floyd$,$ans=min(ans,min(f[n][i][0],f[n][i][1]))$。

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN = 2e3 + 5;
    const double inf = 1e17 + 5;
    int n, m, v, e, c[MAXN][2], mp[305][305];
    double k[MAXN], dp[MAXN][MAXN][2], ans;
    inline int read() {
        char ch = getchar(); int u = 0, f = 1;
        while (!isdigit(ch)) {if (ch == '-')f = -1; ch = getchar();}
        while (isdigit(ch)) {u = u * 10 + ch - 48; ch = getchar();}return u * f;
    }
    int main(){
        memset(mp, 63, sizeof(mp));
        n = read(); m = read(); v = read(); e = read();
        for (register int i = 1; i <= n; i++)c[i][0] = read();
        for (register int i = 1; i <= n; i++)c[i][1] = read();
        for (register int i = 1; i <= n; i++)scanf("%lf", &k[i]);
        for (register int i = 1; i <= e; i++){
            int x = read(), y = read(), w = read();
            mp[x][y] = mp[y][x] = min(mp[x][y], w);
        }
        for (register int k = 1; k <= v; k++)
            for (register int i = 1; i <= v; i++)
                for (register int j = 1; j <= v; j++)
                    mp[i][j] = min(mp[i][j], mp[i][k] + mp[k][j]);
        for (register int i = 1; i <= v; i++)mp[i][i] = mp[i][0] = mp[0][i] = 0;
        for (register int i = 0; i <= n; i++)
            for (register int j = 0; j <= m; j++)dp[i][j][0] = dp[i][j][1] = inf;
        dp[1][0][0] = dp[1][1][1] = 0;
        for (register int i = 2; i <= n; i++){
            dp[i][0][0] = dp[i - 1][0][0] + mp[c[i - 1][0]][c[i][0]];
            for (register int j = 1; j <= min(i, m); j++){
                int C1 = c[i - 1][0], C2 = c[i - 1][1], C3 = c[i][0], C4 = c[i][1];
                dp[i][j][0] = min(dp[i][j][0], min(dp[i - 1][j][0] + mp[C1][C3], dp[i - 1][j][1] + mp[C1][C3] * (1 - k[i - 1]) + mp[C2][C3] * k[i - 1]));
                dp[i][j][1] = min(dp[i][j][1], min(dp[i - 1][j - 1][0] + mp[C1][C3] * (1 - k[i]) + mp[C1][C4] * k[i], dp[i - 1][j - 1][1] + mp[C2][C4] * k[i] * k[i - 1] + mp[C2][C3] * k[i - 1] * (1 - k[i]) + mp[C1][C4] * (1 - k[i - 1]) * k[i] + mp[C1][C3] * (1 - k[i - 1]) * (1 - k[i])));
            }
        }
        ans = inf;
        for (register int i = 0; i <= m; i++)ans = min(ans, min(dp[n][i][0], dp[n][i][1]));
        printf("%.2lf", ans);
        return 0;
    }
  • 相关阅读:
    托付和事件的使用
    在使用supervisord 管理tomcat时遇到的小问题
    无法安装vmware tools的解决方PLEASE WAIT! VMware Tools is currently being installed on your system. Dependin
    (转)Openlayers 2.X加载高德地图
    (转)openlayers实现在线编辑
    (转) Arcgis for js加载百度地图
    (转)Arcgis for js加载天地图
    (转) 基于Arcgis for Js的web GIS数据在线采集简介
    (转) Arcgis for js之WKT和GEOMETRY的相互转换
    (转)Arcgis for Js之Graphiclayer扩展详解
  • 原文地址:https://www.cnblogs.com/Invictus-Ocean/p/12934362.html
Copyright © 2011-2022 走看看