hdu2955_01背包+概率计算

动态规划训练1——hdu2955

                 Robberies
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 32557 Accepted Submission(s): 11815

Problem Description
The aspiring Roy the Robber has seen a lot of American movies, and knows that the bad guys usually gets caught in the end, often because they become too greedy. He has decided to work in the lucrative business of bank robbery only for a short while, before retiring to a comfortable job at a university.

For a few months now, Roy has been assessing the security of various banks and the amount of cash they hold. He wants to make a calculated risk, and grab as much money as possible.

His mother, Ola, has decided upon a tolerable probability of getting caught. She feels that he is safe enough if the banks he robs together give a probability less than this.

 本题为简单的01背包问题,解题步骤及动态规划的状态划分容易得到。但是此题有几个明显的易错点:
   1.此题是概率型问题,计算概率时不能简单相加,而是满足概率运算的基本规则。在本题中,要求被抓的概率严格小于一期望概率。若直接从此角度入手,概率的计算比较困难。因此可考虑计算(1-被抓的概率)>(1-期望)。
   2.由于此题中的概率为浮点数,所以不能用做背包容量,应考虑将所能获得的最大价值作为最大容量。最后查找满足要求的最大价值。

 代码如下:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <string.h>
#include <string>
#include <algorithm>
#include <stdlib.h>
#include <math.h>
using namespace std;
double dp[10005], P[105],pro;
int M[105], N;
int main(void) {
	int T; scanf("%d", &T);
	while (T--) {
		scanf("%lf%d", &pro, &N);
		int sum = 0;
		for (int i = 0; i < N; ++i)
			scanf("%d%lf", &M[i], &P[i]), sum += M[i];
		memset(dp, 0, sizeof(dp)); dp[0] = 1;
		for (int i = N - 1; i >= 0; --i)
			for (int j = sum; j >= M[i]; j--)
				dp[j] = max(dp[j], dp[j - M[i]] * (1 - P[i]));
		for (int i = sum; i >= 0; --i)
			if (dp[i] > 1 - pro) {
				printf("%d\n", i);
				break;
			}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_42663062/article/details/84935875