题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=87125#problem/M

题意:

     一个人想要抢劫银行,每家银行都有一定的金额和被抓到的概率,知道小偷被抓的最大概率P,求他在不被被抓的情况下,抢劫的钱最多是多少。

    案例:

    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

    output

    2 

    4 

    6

思路分析:

       知道小偷在每个银行被抓的概率P[i],则可知小偷成功偷取的概率为1-P[i]。不需要打印,可以写成滚动数组。

       当小偷偷的前为0时,小偷是完全安全的,而在偷取其它金额的开始都是成功率为0,所以要先清零,在给d[0]赋值为1。

       可以对背包问题做一个简单转换,把银行总钱sum作为背包容量C,把(1-p[i])作为重量W,背包问题模版请参考紫书。

       最后,倒叙,找出可以偷出的最多的钱。条件为>(1-P)。

源代码如下:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #define MAX 10005
 6 using namespace std; 
 7 int main()
 8 {
 9     int T,N,m[105];
10     double P,p[105],d[MAX];
11     scanf("%d",&T);
12     while(T--)
13     {
14         int sum=0,i,j;
15         scanf("%lf%d",&P,&N);
16         for(i=0;i<N;i++)
17         {
18             scanf("%d%lf",&m[i],&p[i]);
19             sum+=m[i];
20         }
21         memset(d,0,sizeof(d));                   //初始化
22         d[0]=1;
23         for(i=0;i<N;i++)
24             for(j=sum;j>=m[i];j--)
25                 d[j]=max(d[j],d[j-m[i]]*(1-p[i]));           //状态转移公式
26         for(i=sum;i>=0;i--)
27             if(d[i]>=(1-P))               //找出最多的钱
28             {
29                 printf("%d\n",i);
30                 break;
31             }
32     }
33     return 0;
34 }

 

posted on 2015-08-15 17:18  尘埃。  阅读(229)  评论(0编辑  收藏  举报