HDU 2955

题目大意:有一个小偷要偷银行的钱,可是他偷没家银行总是有一定的概率被抓,现在给了你一个概率P,只要他被抓的概率乘积不大与P,他就是安全的。问你在他安全的情况下,他最多可以偷多少钱。

思路:
做这道题时,错误的认为题目所给的浮点型的数据都是精确到小数点后两位,然后把概率放大100倍,转换成为熟悉的01背包。。faint。。经测试题目的数据可能达到0.00001,甚至比0.00001还小,,所以必须转换思路。

 

于是转成以所有银行的总资产为背包容量sum。。求最大的逃跑概率。。

注意:题目给我们的是被抓的概率,,而我们要求最大的逃跑率,需要去被抓的概率wi的补 ,即1-wi

只有逃跑率才会等于各个逃跑率之积,被抓的概率不会等于各个被抓的概率之积,,概率的知识,不多说。。

状态转移方程:dp[j] = max ( dp[j], dp[j-c[i]] * w[i])..

代码:

View Code
 1 #include<cstdio>
 2 #include<cstring>
 3 int main()
 4 {
 5     int t,i,j,c[10005],m;
 6     double w[10005],dp[10005],n,b;
 7     scanf("%d",&t);
 8     while(t--)
 9     {
10         scanf("%lf %d",&n,&m);
11         int sum=0;
12         for(i=0;i<m;i++)
13         {
14             scanf("%d %lf",&c[i],&b);
15             w[i]=1-b;
16             sum+=c[i];
17         }
18         memset(dp,0,sizeof(dp));
19         dp[0]=1.0;
20         for(i=0;i<m;i++)
21             for(j=sum;j>=c[i];j--)
22             {
23                 if(dp[j]<dp[j-c[i]]*w[i])
24                     dp[j]=dp[j-c[i]]*w[i];
25             }
26             for(i=sum;i>=0;i--)
27                 if(dp[i]>=(1-n))
28                 {
29                     printf("%d\n",i);
30                     break;
31                 }
32     }
33     return 0;
34 }

posted on 2012-08-17 20:36  acoderworld  阅读(65)  评论(0)    收藏  举报

导航