题目:
Robberies
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 26 Accepted Submission(s) : 6
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
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
Bank j contains Mj millions, and the probability of getting caught from robbing it is Pj .
Output
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
题目意思为一个人要去银行抢钱,但是又怕被抓到,所以事先调查了各个银行的钱数和被抓的概率。要求在不被抓到的前提下能偷到的最多的钱。输入第一行为T,表示T组测试数据,接下来一行为被抓的概率和银行的个数,接下来依次为这n家银行的钱数和被抓的概率。
解题思路:
本题如果利用简单的背包问题来解决,有一定的困难,首先在于概率为小于1的数,你可以乘以一个数让他变成整数,但是这样做不现实,程序肯定会超时,因为数据可能达到小数点后的九位数,所以只能转换一下思路,既然有被转的概率p,那么不被抓的概率也就是1-p,不被抓的概率等于各个不被抓的概率的乘积,所以可以刘永不被抓的概率来解决这道题,一下为解题的程序代码。
程序代码:
#include<iostream>
#include<cstring>
using namespace std;
int M[105];
double P[105];
double f[10005];
int main()
{
int T;
cin>>T;
while(T--)
{
memset(M,0,sizeof(M)); 各个数组置零操作
memset(P,0,sizeof(P));
memset(f,0,sizeof(f));
int n,sum=0;
int i,j;
double p,rate;
cin>>p;
cin>>n;
p=1-p; 计算不被抓的概率
for(i=1;i<=n;i++)
{
cin>>M[i];
cin>>rate;
P[i]=1-rate; 输入各个银行不被抓的概率
sum+=M[i]; 计算银行钱数总和。
}
f[0]=1;
for(i=1;i<=n;i++) 背包01,完全可以看伪代码写出来
for(j=sum;j>=M[i];j--)
{
if(f[j-M[i]]*P[i]>f[j]) 不被抓的概率等于各个不被抓的概率的乘积
f[j]=f[j-M[i]]*P[i];
}
for(i=sum;i>=0;i--) 输出最大的可以得到的钱数
if(f[i]>p)
{
cout<<i<<endl;
break;
}
}
return 0;
}
解题感想;
本题的解题思路与其他01背包题目有所不同在于从所给问题的反面来解决这个问题,这也是一个很重要的思想,从事物的反面来做,有时候会得到意想不到的结果,而且可以简化题目,通过这道题,也让我领悟到在以后的解题过程中可以从题目的相反反面来考虑,总之,这道题目不仅仅可以更加熟悉背包问题的解决更加可以锻炼我们的思维能力。是一道很不错的题目。