H - Island of Survival LightOJ - 1265

這道題目,我看了好多篇博客,都沒有看到過很好的解釋, 不過在這位大佬這裏看到了,很棒的解釋。

點擊打開鏈接

用的是概率dp做的,dp[i][j]表示的是有i只老虎和j只鹿的情況下,人的最大存活概率,因爲dp[0][j]都是0可以從下往上遞推;

狀態轉移方程是:

我們只要解一下這個方程,把dp[i][j],移到一邊就可以了。

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cstring>
using namespace std;
#define Max_N 1010
int T, n, m;
double dp[Max_N][Max_N];
int main()
{
	scanf("%d", &T);
	int num = 0;
	while (T--) {
		scanf("%d%d", &n, &m);
		num++;
		if(n%2) {
			printf("Case %d: 0\n", num);
			continue;
		}
		memset(dp, 0, sizeof(dp));
		for (int i = 0; i <= m; i++)
			dp[0][i] = 1;
		for (int i = 1; i <= n; i++) {
			for (int j = 0; j <= m; j++) {
				double r1, r2;
				r1 = 0;
				r2 = 0;
				if (i >= 2)	
					r1 += i * (i - 1) * 1.0 / ((i + j + 1) * (i + j)) * dp[i-2][j];
				if (j >= 1)
					r1 += j * i * 2.0 / ((i + j + 1) * (i + j)) * dp[i][j-1];
				 double p = 0;
                if (j >= 2) {
                    p = (j * (j - 1) * 1.0) / ((i + j + 1) * (i + j));
                }
                if (j >= 1) {
                    r2 = r1;
                    r2 += j * 2.0 / ((i + j + 1) * (i + j)) * dp[i][j - 1];
                    r2 /= (1 - p);
                }
                r1 /= (1 - p - j * 2.0 / ((i + j + 1) * (i + j)));
                dp[i][j] = max(r1, r2);	
		
			}
		}
		printf("Case %d: %.12f\n", num, dp[n][m]);

	}
	return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章