题意:哈利波特想去挣快钱。他决定去抢银行,但是他的朋友-赫敏和罗恩觉得他会有p概率被抓住,他们认为他安全,如果他被抓的概率低于p。

分析:设f[i][j]为前i个银行抢劫j元被抓的概率,如果对于当前不抢劫银行的决策,那么f[i][j] = f[i - 1][j],否则f[i][j] = f[i - 1][j - m[i]] + (1 - f[i - 1][j - m[i]]) * p[i]。
另一个决策为什么要加起来呢?(1 - f[i - 1][j - m[i]])表示抢劫前i - 1个银行,抢劫j - m[i]不被抓的概率,那么到第i个银行被抓,就要相乘,是独立的两个事件。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>

using namespace std;

const int N = 105;
const int M = 10005;
struct Node
{
	int m;
	double p;
}b[N];

double f[N][M];

int main()
{
	int t;
	scanf("%d", &t);

	int c = 0;
	while (t--)
	{
		//可以忍受的概率
		double p;
		scanf("%lf", &p);

		int n;
		scanf("%d", &n);

		int sum = 0;
		for (int i = 1; i <= n; ++i)
		{
			scanf("%d%lf", &b[i].m, &b[i].p);
			sum += b[i].m;
		}

		for (int j = 1; j <= sum; ++j)
			f[0][j] = 1;

		for(int i = 1; i <= n; ++i)
			for (int j = 1; j <= sum; ++j)
			{
				f[i][j] = min(f[i - 1][j], f[i - 1][j - b[i].m] + (1 - f[i - 1][j - b[i].m]) * b[i].p);
			}

		int res = 0;

		for (int j = 1; j <= sum; ++j)
		{
			if (f[n][j] < p)
				res = j;
		}

		printf("Case %d: %d\n", ++c, res);
	}



	return 0;
}