Robberies HDU - 2955

原题链接

考察:01背包

错误思路:

       把概率*100当作体积

此思路错在小数点不止两位...

正确思路:

       参考上一题把牛的智商当作体积,这题可以把钱当作体积.从大到小遍历,如果当前的概率能逃脱就break出

       但是这道题,概率应该用逃脱后的概率,如果用被捕概率应该是:前i家银行被捕概率是第一家银行被捕+第一家银行不被捕*第二家银行被捕+...(但是用补集好算地多)

       还有这道题的概率是相乘不是相加.

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 using namespace std;
 6 const double eps = 1e-8;
 7 const int N = 11000,M = 110;
 8 int money[M];
 9 double arrest[M],f[N];//小数可能不止两位... 
10 int main() 
11 {
12     int T;
13     scanf("%d",&T);
14     while(T--)
15     {
16         double v; int n,sum = 0; bool ok = 0;
17         scanf("%lf%d",&v,&n);
18         memset(f,0,sizeof f);//因为是相乘,所以不可能的情况一直是0 
19         f[0] = 1; v = 1-v;
20         for(int i=1;i<=n;i++)
21         {
22             double arr; scanf("%d%lf",&money[i],&arrest[i]);
23             arrest[i] = 1-arrest[i];
24             sum+=money[i];
25         }
26         for(int i=1;i<=n;i++)
27           for(int j=sum;j>=money[i];j--)
28           {
29                 f[j] = max(f[j],f[j-money[i]]*arrest[i]);
30           }
31         for(int i=sum;i>=0;i--)
32             if(f[i]>=v) { printf("%d\n",i);ok = 1; break; }
33         if(!ok) printf("0\n");
34     }
35     return 0;
36 }

 

posted @ 2021-02-02 01:25  acmloser  阅读(35)  评论(0编辑  收藏  举报