Hdu 2955 Robberies 0/1揹包

Robberies

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 10526    Accepted Submission(s): 3868


ios

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
 
   這是一道關於01揹包的問題,題目的意思是有個強盜想去搶劫銀行,可是又不想被抓到,因此,他要計算不被抓到的狀況下能夠得到的最大的金錢數目。首先給定一個數T表示有T組測試數據,而後是兩個數P和N,P表示被抓的概率,N表示有三家銀行,接下來N行是每家銀行搶到的金錢和被抓的概率,輸出不被抓的狀況下能夠搶到的最大的金額。
  首先咱們能夠算出不被抓的概率和最多能夠搶到的金錢,而後在這種狀況下至關於01揹包問題。不過要注意的是狀態轉移方程是dp[i] = max(dp[i],dp[i-m[i]]*p[i]),而不是dp[i] = max(dp[i],dp[i-m[i]]+p[i]),這一點至關重要,也是解題的關鍵。
 
提供參考代碼:
 1 #include <iostream>
 2 #include <cstdio>
 3 using namespace std;
 4 #define MAX 10003
 5 double p[MAX],f[MAX];
 6 int m[103];
 7 int main()
 8 {
 9     double P;
10     int T, N, i, j;
11     cin>>T;
12     while(T--)
13     {
14         int sum = 0;
15         scanf("%lf %d",&P,&N);
16         P = 1-P;    //不被抓的機率
17         for(i=0; i<N; i++)
18         {
19             scanf("%d %lf",&m[i],&p[i]);
20             p[i] = 1-p[i];  //不被抓的機率
21             sum += m[i]; //能夠搶到的最大金錢數目
22         }
23         
24         for(i=0; i<=sum; i++)
25             f[i] = 0;
26         f[0] = 1;     //表示搶金錢爲0的時候,不被抓的機率爲1
27         for(i=0; i<N; i++)
28             for(j=sum; j>=m[i]; j--)
29                 f[j] = max(f[j],f[j-m[i]]*p[i]);
30         for(i=sum; i>=0; i--)  //從最大的金錢數目開始,依次查看不被抓機率是否和給定的相等
31             if(f[i]-P>0.000000001)
32             {
33                 cout<<i<<endl;
34                 break;
35             }
36     }
37     return 0;
38 }    
View Code
相關文章
相關標籤/搜索