SRM 603 D2 L3:GraphWalkWithProbabilities

题目来源:http://community.topcoder.com/tc?module=ProblemDetail&rd=15836&pm=12908

参考:http://apps.topcoder.com/wiki/display/tc/SRM+603


这题做的时候完全没思路,看了这里之后才懂了,搞懂这题关键是要想到 在每个点的状态是无记忆性的,即在每个点赢的概率与之前游戏的情况无关。

数组 p[i][t] 表示 从点i出发,最多经过t 轮之后,能赢的概率。只要t足够大,p[i][t]的值就近似是真实值,因为题目要求可以有1e-9的误差。

而p[i][k]的计算又依赖于p[j][k-1]的值,j 表示 可以 i 到达 的点(即graph[i][j] == ‘1‘ ),注意 j 可以 与 i 相同,即点停在原处。有:

p[i][k] = max ( 对所有的 j : w[j] + (1-w[j]-l[j]) * p[j][k-1]). 

代码:

#include <algorithm>
#include <iostream>
#include <sstream>

#include <string>
#include <vector>
#include <stack>
#include <deque>
#include <queue>
#include <set>
#include <map>

#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <cstring>

using namespace std;


/*************** Program Begin **********************/
const int MAX_TURNS = 3000;
const int MAX_V = 50;
double p[MAX_V][MAX_TURNS + 1];


class GraphWalkWithProbabilities {
public:
    double findprob(vector <string> graph, vector <int> winprob, vector <int> looseprob, int Start) {
	    for (int i = 0; i < MAX_V; i++) {
		p[i][0] = 0.0;
	    }
	    int N = graph.size();
	    for (int k = 1; k <= MAX_TURNS; k++) {
		for (int i = 0; i < N; i++) {
			p[i][k] = 0.0;
			for (int j = 0; j < N; j++) {
				if (graph[i][j] == ‘1‘) {
					p[i][k] = max( p[i][k], 
						winprob[j] / 100.0 + (100 - winprob[j] - looseprob[j]) / 100.0 * p[j][k-1]);
				}
			}
		}
	    }
	    return p[Start][MAX_TURNS];
    }

};

/************** Program End ************************/


SRM 603 D2 L3:GraphWalkWithProbabilities

上一篇:2013年:各大IT公司待遇【转载】


下一篇:??AIX 关于vg的基本命令