HDU 2955 Robberies 动态规划01背包

http://acm.hdu.edu.cn/showproblem.php?pid=2955

题意:

  第一行第一个小数,是这个人被抓住的概率最大不能超过这个数,第二个是有N个银行。一个整数和小数分别为这个银行有多少钱和被这个银行

抓住的概率。求出这个小偷在不超过自己抓住的最大概率中抢更多的银行。

 

坑爹:

  f 数组 初始化为0 ,但是 f [0] 要为1,因为不抢任何银行的时候永远是成功的。所有银行的钱数加起来是“背包”的容量,不被抓的概率是价

值。

 

解法:

  套用01背包的状态转移方程,解出不被抓住的概率,然后用1减去它,再和被抓住的概率比较。

 

View Code
 1 #include<iostream>
 2 using namespace std;
 3 
 4 const int maxn = 10000 + 10;
 5 int price[maxn];
 6 double chance[maxn];
 7 double f[maxn];
 8 int sum;
 9 
10 double max(double a,double b)
11 {
12     return a>b?a:b;
13 }
14 
15 void ZeroOnePack(int cost,double weight)
16 {
17     int j;
18     for(j=sum; j>=cost; j--)
19     {
20         f[j]=max(f[j],f[j-cost]*weight);
21     }
22 }
23 
24 int main()
25 {
26     int T;
27     cin>>T;
28     while(T--)
29     {
30         int N;
31         double P;
32         cin>>P>>N;
33         int i;
34         P=1-P;
35         
36         sum=0;
37         for(i=1; i<=N; i++)
38         {
39             cin>>price[i]>>chance[i];
40             chance[i]=1-chance[i]; 
41             sum+=price[i];
42         }
43         
44         memset(f,0,sizeof(f));
45         f[0]=1.0;
46         for(i=1; i<=N; i++)
47         {
48             ZeroOnePack(price[i],chance[i]);
49         }
50 
51 
52         for(i=sum; i>=0; i--)
53         {
54             if(f[i]>P)
55             {
56                 printf("%d\n",i);
57                 break;
58             }
59         }
60         
61     }
62     return 0;
63 }

 

  

posted @ 2012-09-06 16:40  pc....  阅读(188)  评论(0)    收藏  举报