Robberies
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4852 Accepted Submission(s): 1844
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.

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.
Input
The first line of input gives T, the number of cases. For each scenario, the first line of input gives a floating point number P, the probability Roy needs to be below, and an integer N, the number of banks he has plans for. Then follow N lines, where line j gives an integer Mj and a floating point number Pj .
Bank j contains Mj millions, and the probability of getting caught from robbing it is Pj .
Bank j contains Mj millions, and the probability of getting caught from robbing it is Pj .
Output
For each test case, output a line with the maximum number of millions he can expect to get while the probability of getting caught is less than the limit set.
Notes and Constraints
0 < T <= 100
0.0 <= P <= 1.0
0 < N <= 100
0 < Mj <= 100
0.0 <= Pj <= 1.0
A bank goes bankrupt if it is robbed, and you may assume that all probabilities are independent as the police have very low funds.
Notes and Constraints
0 < T <= 100
0.0 <= P <= 1.0
0 < N <= 100
0 < Mj <= 100
0.0 <= Pj <= 1.0
A bank goes bankrupt if it is robbed, and you may assume that all probabilities are independent as the police have very low funds.
Sample Input
3
0.04 3
1 0.02
2 0.03
3 0.05
0.06 3
2 0.03
2 0.03
3 0.05
0.10 3
1 0.03
2 0.02
3 0.05
Sample Output
2
4
6
分析:求解可抢劫最大金钱数且不被抓,照正常背包问题来讲,概率存在界限,为背包体积,最优解目标是金钱数应该是价值,但是概率为浮点数不能作为背包体积。那么背包体积为金钱数,价值为概率,使概率尽可能的小,且0-1背包问题变形为0-1背包刚好装满的问题。
这两个问题的区别就在于0-1初始赋值应该都为0或其他同样的值。而刚好装满的问题的初值应该为体积为0的时候有初值,而其他为“无穷”。为什么仅仅初值变化就变成了不同的问题?因为由此dp[i][j]的含义便不同了,前者的含义为背包体积不超过j,且遍历到i个物品时的最大/最小价值,而后者的含义为背包体积恰好为j,且遍历到i个物品时的最大/最小值。这样的话,不能恰好装满的j对应的价值都为无穷(如果dp[j-m[i]]==0,则是加入一个物品时,体积刚好满,依次类推,只要dp[j-m[i]]不等于无穷,说明存在减去当前物品体积的值,刚好“装满”),而前者对应的价值是依然存在的。
本题还有一个关键:相互独立事件的概率。要求被抓的概率不好求,转而求不被抓的概率,根据相互独立事件的概率相乘原理,P(不被抓)=∏ P(抢第i家不被抓)
综上所述,代码如下:
#include <stdio.h>
double dp[10001];
int m[101];
double p[101];
double p_max(double a,double b)
{
return a>b?a:b;
}
int main(int argc, char** argv) {
int T;
scanf("%d",&T);
while(T--)
{
//这里概率均用不被抓的概率
int N,M;
double pmax;
scanf("%lf%d",&pmax,&N);
//不被抓的概率阈值,不能低于这个值
pmax=1-pmax;
int i,j;
M=0;
for(i=1;i<=N;i++)
{
scanf("%d%lf",&m[i],&p[i]);
//不被抓的概率
p[i]=1-p[i];
//记录最大可达到的金钱数
M+=m[i];
}
//刚好装满背包,除了第一个赋值为1,其他均为0(可看作无穷小),这样的话,如果不能正好装满背包的值得对应概率为0,且如果最后无解也会输出0
for(i=1;i<=M;i++) dp[i]=0;
dp[0]=1;
for(i=1;i<=N;i++)
{
//j要大于等于lst[i].m,若j小于lst[i].m则总金额为j时,不可能将本次lst[i]放入,不进入这样的循环,不进行任何操作,dp[j]依然为之前的dp[j]
for(j=M;j>=m[i];j--)
{
dp[j]=p_max(dp[j],dp[j-m[i]]*p[i]);
}
}
//从后往前遍历 输出第一个概率大于阈值的钱数
for(j=M;j>=0;j--)
{
if(dp[j]>=pmax)
{
printf("%d\n",j);
break;
}
}
}
return 0;
}