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 ************************/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值