Robberies
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 32415 Accepted Submission(s): 11765
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.
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 .
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.
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
始用贪心算的这个题,算他们每组的价值比,后来WA了6次,还是乖乖用动态规划吧
题目大意:
给一个概率限制,当概率大于他抢劫银行被抓的概率就代表他可以获得这个银行的钱
给出n个银行,让为我们计算可以获得的最大金钱数。
首先,概率是不能直接加减的,所以不能把概率看作是背包容量,只能是金钱数;
将被抓的概率换成逃跑的概率,逃跑的概率=n*(1-p),n代表当前银行的金钱数,P代表当前概率。
只要逃跑的概率大于该概率就可以逃跑,用DP算出所有的概率,从大到小寻找最适合的概率。
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
//#include<bits/stdc++.h>
#define x 100001
using namespace std;
int main()
{
int t,m;
double p1,p[x],dp[x];
int n[x];
cin>>t;
while(t--)
{
int sum=0;
memset(p,0,sizeof(p));
memset(n,0,sizeof(n));
memset(dp,0,sizeof(dp));
cin>>p1>>m;
for(int i=0;i<m;i++)
{
cin>>n[i]>>p[i];
sum+=n[i]; //总钱数
}
dp[0]=1; //dp代表逃走的概率,开始为1
for(int i=0;i<m;i++)
{
for(int j=sum;j>=n[i];j--)
{
dp[j]=max(dp[j],dp[j-n[i]]*(1.0-p[i]));
//cout<<j<<":"<<dp[j]<<endl;
//将所有的逃跑概率计算出来,选大于逃跑界限的最小逃跑概率,对应的就是最大的钱数
}
}
for(int i=sum;i>=0;i--)
{
if(dp[i]>=(1-p1))
{
printf("%d\n",i);
break;
}
}
}
return 0;
}
DP这方面还是很方,公式总是写不出来,继续加油吧!