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 }