HDU 3366 Passage 概率dp

Passage

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 538    Accepted Submission(s): 269


Problem Description
Bill is a millionaire. But unfortunately he was trapped in a castle. There are only n passages to go out. For any passage i (1<=i<=n), Pi (0<=Pi<=1) denotes the probability that Bill will escape from this castle safely if he chose this passage. Qi (0<=Qi<=1-Pi) denotes the probability that there is a group of guards in this passage. And Bill should give them one million dollars and go back. Otherwise, he will be killed. The probability of this passage had a dead end is 1-Pi-Qi. In this case Bill has to go back. Whenever he came back, he can choose another passage.
We already know that Bill has M million dollars. Help Bill to find out the probability that he can escape from this castle if he chose the optimal strategy.
 

Input
The first line contains an integer T (T<=100) indicating the number of test cases.
The first line of each test case contains two integers n (1<=n<=1000) and M (0<=M<=10).
Then n lines follows, each line contains two float number Pi and Qi.
 

Output
For each test case, print the case number and the answer in a single line.
The answer should be rounded to five digits after the decimal point.
Follow the format of the sample output.
 

Sample Input
 
   
3 1 10 0.5 0 2 0 0.3 0.4 0.4 0.5 3 0 0.333 0.234 0.353 0.453 0.342 0.532
 

Sample Output
 
   
Case 1: 0.50000 Case 2: 0.43000 Case 3: 0.51458

题意:某人被困在迷宫中,并且有m million钱,迷宫有n条路,每条路可直接出去的概率为p,遇到守卫的概率为q(这时需要给守卫1 million钱,并且返回,没有钱就会被杀死),还有1-p-q的概率是此路不通。问能够逃出去的最大概率是多少。

解析:使用概率dp做。dp[i][j]表示要选第i条路时,还有j million钱。要先按照能够逃出去的概率对这些道路排序,即对p/(p+q)排序,然后依次走每条路。每条路分为三种情况:

1、直接出去:ans += dp[i][j]*A[i].p

2、遇到守卫且钱充足:dp[i+1][j-1] = dp[i][j]*A[i].q

3、此路不通,返回走别的路:dp[i+1][j] = dp[i][j]*(1-A[i].p-A[i].q)

代码:

#include 
#include 
#include 
using namespace std;
#define N 1005
struct node{
	double p, q;
	bool operator < (const node &a)const{
		return p/(q+p) > a.p/(a.q+a.p);
	}
}A[N];
double dp[N][11];

int main(){
	int t, n, m, cas = 0;
	scanf("%d", &t);
	while(t--){
		scanf("%d%d", &n, &m);
		for(int i = 0; i < n; i++)
			scanf("%lf%lf", &A[i].p, &A[i].q);
		memset(dp, 0, sizeof(dp));
		sort(A, A+n);
		dp[0][m] = 1.0;
		double ans = 0.0;
		for(int i = 0; i < n; i++){
			for(int j = m; j >= 0; j--){
				ans += dp[i][j]*A[i].p;
				dp[i+1][j] += dp[i][j]*(1.0-A[i].p-A[i].q);
				if(j-1>=0) dp[i+1][j-1] += dp[i][j]*A[i].q;
			}
		}
		printf("Case %d: %.5lf\n",++cas, ans);
	}
	return 0;
}

你可能感兴趣的:(算法,------动态规划,算法,dp)