HDU 4815 : Little Tiger vs. Deep Monkey

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4815

题目大意:n个问题,每个问题不同分值只有两个选项,随机选,给一个概率P,求最少有多少分才能保证赢的概率不小于P、

解题思路:很容易想到是动态规划,然而有什么用呢?哈哈

注意到每个题目的可能价值比较小,总价值最多不过4e4,用dp[i][j]表示做前i道题得到j分的概率,最后从0到总价值遍历一遍,直到概率不小于P就输出当前分数即可。

考虑状态转移方程(其实子状态知道了这就不难了):

无非就是答对与答错

答对:dp[i+1][j+val[i+1]] += dp[i][j] * 0.5

答错:dp[i+1][j] += dp[i][j] * 0.5

考虑如何找到答案:

显然有dp[n][0] + dp[n][1] + .. + dp[n][sum] = 1

dp[n][0] + dp[n][1] + dp[n][m] = 做n道题得到不少于m分的概率

所以我们想得到概率不小于p就一直加dp[n][i],当不小于p的时候,答案就表示不少于m分,也就是不输,这个时候的i就是要求的最少的分数。

AC Code:

#include<set>
#include<map>
#include<cmath>
#include<ctime>
#include<queue>
#include<cstdio>
#include<string>
#include<vector>
#include<cstdlib>
#include<cstring>
#include<iomanip>
#include<iostream>
#include<algorithm>
#define fi first
#define se second
#define pb push_back
#define lowbit(x) x&(-x)
#define PII  pair<int, int> 
#define all(x) x.begin(), x.end()
#define FAST ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int mod = (int)1e9 + 7;
const int maxn = (int)50;
using namespace std;

int val[maxn];
double dp[45][40005];

int main()
{
	int t; scanf("%d", &t);
	while(t--){
		memset(dp, 0, sizeof(dp));
		int n; double P;
		scanf("%d %lf", &n, &P);
		int sum = 0;
		for(int i = 1; i <= n; i++) scanf("%d", val + i), sum += val[i];
		dp[0][0] = 1.0;
		for(int i = 0; i < n; i++){
			for(int j = 0; j <= sum - val[i+1]; j++){
				if(dp[i][j]){
					dp[i+1][j+val[i+1]] += dp[i][j] * 0.5;
					dp[i+1][j] += dp[i][j] * 0.5;
				}
			}
		}
		double p = 0;
		for(int i = 0; i <= sum; i++){
			p += dp[n][i];
			if(p >= P){
				printf("%d\n", i);
				break;
			}
		}
	}
	return 0;
}

over.

猜你喜欢

转载自blog.csdn.net/swunHJ/article/details/82108612