zoukankan      html  css  js  c++  java
  • 【NOIP16提高组】换教室

     【题目链接】

              点击打开链接

     【算法】

              概率DP

              先跑一遍floyed,求出每个教室之间的最短路径,存在数组dist[][]中,时间复杂度O(V^3)

              设计状态,f[i][j][k]表示当前选到第i个教室,已经选了j个教室,当前这个教室选不选(0..1)

              那么,状态转移方程是什么呢?

              假设当前选到第i个教室,已经选了j个教室,那么,如果不选这个教室,则状态转移方程为

              f[i][j][0] = max{f[i-1][j][0]+dist[c[i-1]][c[i]],f[i-1][j][1]+dist[c[i-1]][c[i]]*(1-k[i-1])+dist[d[i-1]][c[i]]*k[i-1]}

          如果选这个教室,则状态转移方程是

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

          于是这道题便迎刃而解了!

          【代码】

       

    #include<bits/stdc++.h>
    using namespace std;
    #define MAXN 2000
    #define MAXV 300
    
    int i,j,k,n,m,v,e,a,b,w;
    int dist[MAXV+10][MAXV+10],c[MAXN+10],d[MAXN+10];
    double P[MAXN+10],dp[MAXN+10][MAXN+10][2];
    double ans = 2e9;
    
    template <typename T> inline void read(T &x) {
            int f=1; x=0;
            char c = getchar(); 
            for (; !isdigit(c); c = getchar()) { if (c == '-') f = -f; }
            for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
            x *= f;
    }
    
    template <typename T> inline void write(T x) {
        if (x < 0) { putchar('-'); x = -x; }
        if (x > 9) write(x/10);
        putchar(x%10+'0');    
    }
    
    template <typename T> inline void writeln(T x) {
        write(x);
        puts("");    
    }
    
    int main() {
            
            read(n); read(m); read(v); read(e);
            for (i = 1; i <= v; i++) {
                    for (j = 1; j <= v; j++) {
                            if (i != j)
                                    dist[i][j] = 2e9;
                    }
            }
             for (i = 1; i <= n; i++) read(c[i]);
            for (i = 1; i <= n; i++) read(d[i]);
            for (i = 1; i <= n; i++) cin >> P[i];
            for (i = 1; i <= e; i++) {
                    read(a); read(b); read(w);
                    dist[a][b] = min(dist[a][b],w);
                    dist[b][a] = min(dist[b][a],w);    
            }
        
            for (k = 1; k <= v; k++) {
                    for (i = 1; i <= v; i++) {
                            if (i == k) continue;
                            if (dist[i][k] == 2e9) continue;
                            for (j = 1; j <= v; j++) {
                                    if (dist[k][j] == 2e9) continue;
                                    if ((i == j) || (k == j)) continue;
                                    dist[i][j] = min(dist[i][j],dist[i][k]+dist[k][j]);
                            }
                    }
            }    
            
            for (i = 1; i <= n; i++) {
                    for (j = 0; j <= m; j++) {
                            dp[i][j][0] = dp[i][j][1] = 2e9;
                    }    
            }
            
            dp[1][0][0] = 0; dp[1][1][1] = 0;
            for (i = 2; i <= n; i++) {
                    dp[i][0][0] = dp[i-1][0][0] + dist[c[i-1]][c[i]];
                    for (j = 1; j <= min(i,m); j++) {
                            dp[i][j][0] = min(dp[i-1][j][0]+dist[c[i-1]][c[i]],dp[i-1][j][1]+dist[c[i-1]][c[i]]*(1.0-P[i-1])+dist[d[i-1]][c[i]]*P[i-1]);
                            dp[i][j][1] = min(dp[i-1][j-1][0]+dist[c[i-1]][d[i]]*P[i]*1.0+dist[c[i-1]][c[i]]*(1.0-P[i]),
                                                                dp[i-1][j-1][1]+
                                                                dist[d[i-1]][d[i]]*P[i-1]*P[i]*1.0+ 
                                                                dist[c[i-1]][d[i]]*(1.0-P[i-1])*P[i]+ 
                                                                dist[c[i-1]][c[i]]*(1.0-P[i-1])*(1.0-P[i])+ 
                                                                    dist[d[i-1]][c[i]]*P[i-1]*(1-P[i])*1.0); 
                    }    
            }
            
            for (i = 0; i <= m; i++) ans = min(ans,min(dp[n][i][0],dp[n][i][1]));
            cout<< fixed << setprecision(2) << ans << endl;
            
            return 0;
        
    }
    
    
             
    
                
  • 相关阅读:
    3个简单易懂的项目技巧
    使用HTML和CSS实现3D文字效果
    星巴克咖啡杯svg特效
    Web移动端实现自适应缩放界面的方法汇总
    javscript 闭包应用介绍
    pytest命令行传参
    vue7:父组件向子组件传值
    vue6:子组件向父组件传值
    vue5: is规避错误
    vue4:refs介绍
  • 原文地址:https://www.cnblogs.com/evenbao/p/9196423.html
Copyright © 2011-2022 走看看