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

    P1850 换教室

    现在有一张图, 有 (v <= 300) 个节点
    你需要从 (c_{1})(c_{2})(c_{n} (n <= 2000))
    现在你有 (m) 次机会把 (c_{i}) 换为 (d_{i}), 对于第 (i) 个, 成功的概率为 (k_{i})
    求走完整个路程的期望路径长度


    错误日志: 作死赋值 (double)(memset)


    Solution

    这是第一个有关期望的题呢
    本题为期望 (dp) , 从上一个状态转移过来(听dalao说还有一种是计算本状态对后面状态的贡献)
    具体来说, 这个状态可以由以上 (n) 个状态得到, 每个状态权值为 (w_{i}), 其中第 (i) 个状态到此状态的概率为 (k_{i}), 那么有此状态可以表示为 $$dp[now] = sum_{i = 1}^{n}{w_{i} * k_{i}}$$
    本题状态为:
    (dp[i][j][0/1]) 代表选到第 (i) 门课用掉 (j) 次机会, 此次申请或不申请的期望值
    所有转移详细记录在注释中
    答案自然在 (min_{i = 0}^{m}{min(dp[n][i][0], dp[n][i][1])})

    Code

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    #include<algorithm>
    #include<climits>
    #define LL long long
    #define REP(i, x, y) for(int (i) = (x);(i) <= (y);(i)++)
    using namespace std;
    int RD(){
        int out = 0,flag = 1;char c = getchar();
        while(c < '0' || c >'9'){if(c == '-')flag = -1;c = getchar();}
        while(c >= '0' && c <= '9'){out = out * 10 + c - '0';c = getchar();}
        return flag * out;
        }
    const int maxn = 4019, maxv = 319;
    int num, numc, numv, nr;
    int map[maxv][maxv];
    int c[maxn], d[maxn];
    double k[maxn];
    double dp[maxn][maxn][2];
    void floyd(){
    	REP(i, 1, numv)map[i][i] = 0;
    	REP(k, 1, numv)REP(i, 1, numv)REP(j, 1, numv){
    		map[i][j] = min(map[i][j], map[i][k] + map[k][j]);
    		}
    	}
    int dist(int x, int y){return map[x][y];}
    void init(){
    	REP(i, 1, numv)REP(j, 1, numv)map[i][j] = 1e9;
    	REP(i, 1, num)REP(j, 0, numc)dp[i][j][0] = dp[i][j][1] = 1e9;
    	}
    int main(){
    	num = RD(), numc = RD(), numv = RD(), nr = RD();
    	init();
    	REP(i, 1, num)c[i] = RD();
    	REP(i, 1, num)d[i] = RD();
    	REP(i, 1, num)cin>>k[i];
    	REP(i, 1, nr){
    		int u = RD(), v = RD(), dis = RD();
    		map[u][v] = min(map[u][v], dis);
    		map[v][u] = map[u][v];
    		}
    	floyd();
    	dp[1][0][0] = dp[1][1][1] = 0;//选或不选都为起点
    	REP(i, 2, num){
    		int m = min(numc, i);
    		REP(j, 0, m){//可以不申请换教室, 从0开始
    			dp[i][j][0] = min(//本次不申请
    			dp[i - 1][j][0] + dist(c[i], c[i - 1]),//上次不申请
    			dp[i - 1][j][1]//上次申请
    			+ dist(c[i], d[i - 1]) * k[i - 1]//申请成功
    			+ dist(c[i], c[i - 1]) * (1 - k[i - 1])//申请失败
    			);
    			if(!j)continue;
    			dp[i][j][1] = min(//本次申请
    			dp[i - 1][j - 1][0]//上次不申请
    			+ dist(d[i], c[i - 1]) * k[i]//本次成功
    			+ dist(c[i], c[i - 1]) * (1 - k[i]), //本次失败
    			dp[i - 1][j - 1][1]//上次申请
    			+ dist(c[i], c[i - 1]) * (1 - k[i]) * (1 - k[i - 1])//0->0
    			+ dist(d[i], c[i - 1]) * k[i] * (1 - k[i - 1])//0->1
    			+ dist(c[i], d[i - 1]) * (1 - k[i]) * k[i - 1]//1->0
    			+ dist(d[i], d[i - 1]) * k[i] * k[i - 1]//1->1
    			);
    			}
    		}
    	double ans = 100000019;
    	REP(i, 0, numc){
    		ans = min(ans, dp[num][i][0]);
    		ans = min(ans, dp[num][i][1]);
    		}
    	printf("%.2lf
    ", ans);
    	return 0;
    	}
    
  • 相关阅读:
    Java Spring MVC框架搭建(一)
    LeetCode 239. Sliding Window Maximum(Hard)
    LeetCode 238. Product of Array Except Self
    LeetCode 237 Delete Node in a Linked List
    LeetCode 236. Lowest Common Ancestor of a Binary Tree
    LeetCode 235 Lowest Common Ancestor of a Binary Search Tree
    LeetCode 234. Palindrome Linked List
    LeetCode 232. Implement Queue using Stacks
    LeetCode 231. Power of Two
    LeetCode 230. Kth Smallest Element in a BST
  • 原文地址:https://www.cnblogs.com/Tony-Double-Sky/p/9748890.html
Copyright © 2011-2022 走看看