Robberies
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 17647 Accepted Submission(s): 6516
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.
Bank j contains Mj millions, and the probability of getting caught from robbing it is Pj .
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.
題目意思是給定給定一個概率,是被抓的概率,給定幾個銀行,每個銀行對應一個錢數和被抓的概率,如何在有效的被抓概率內偷更多的錢?
顯然是個0-1揹包的問題,一開始把這個當成了一個概率簡單相加的問題,看了討論區發現傻了。。其實概率應該是相乘的。設個一維DP,代表對應money被抓的概率,最後反向尋找第一個概率大於1 - 被抓的概率的就好。
代碼如下:
/*************************************************************************
> File Name: 0-1_bags.cpp
> Author: Zhanghaoran
> Mail: [email protected]
> Created Time: Fri 27 Nov 2015 11:21:43 PM CST
************************************************************************/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstdlib>
using namespace std;
float dp[10010];
int main(void){
int T, n;
float p;
int mon[10010];
float pro[10010];
int all = 0;
cin >> T;
while(T --){
all = 0;
scanf("%f%d",&p,&n);
memset(dp, 0, sizeof(dp));
for(int i = 1; i <= n; i ++){
scanf("%d%f",&mon[i],&pro[i]);
all += mon[i];
}
dp[0] = 1;
for(int i = 1; i <= n; i ++){
for(int j = all; j >= mon[i]; j --){
dp[j] = max(dp[j], dp[j - mon[i]] * (1 - pro[i]));
}
}
for(int i = all; i >= 0; i --){
if(dp[i] >= (1 - p)){
printf("%d\n", i);
break;
}
}
}
return 0;
}