题意:哈利波特想去挣快钱。他决定去抢银行,但是他的朋友-赫敏和罗恩觉得他会有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;
}