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;
        
    }
    
    
             
    
                
  • 相关阅读:
    简明Python3教程 12.问题解决
    简明Python3教程 11.数据结构
    【SPOJ 694】Distinct Substrings
    【codeforces Manthan, Codefest 17 C】Helga Hufflepuff's Cup
    【CF Manthan, Codefest 17 B】Marvolo Gaunt's Ring
    【CF Manthan, Codefest 17 A】Tom Riddle's Diary
    【SPOJ 220】 PHRASES
    【POJ 3261】Milk Patterns
    【POJ 3294】Life Forms
    【POJ 1226】Substrings
  • 原文地址:https://www.cnblogs.com/evenbao/p/9196423.html
Copyright © 2011-2022 走看看