【01背包变形】Robberies HDU 2955
http://acm.hdu.edu.cn/showproblem.php?pid=2955
【题意】
有一个强盗要去几个银行偷盗,他既想多抢点钱,又想尽量不被抓到。已知各个银行
的金钱数和被抓的概率,以及强盗能容忍的最大被抓概率。求他最多能偷到多少钱?
【思路】
01背包:每个物品代价是每个银行钱的数目,物品的价值是在该银行不被抓的概率 (1-被抓概率),背包容量是所有银行钱的总和。01背包求dp[i]表示获得i的钱不被抓的最大概率。最后从大到小枚举出 dp[i]>=(1-P)这个i就是答案了。
【AC】
1 #include<iostream> 2 #include<cstdio> 3 #include<string> 4 #include<cstring> 5 #include<algorithm> 6 #include<cmath> 7 #include<queue> 8 9 using namespace std; 10 typedef long long ll; 11 const int maxn=1e2+3; 12 double P; 13 int n; 14 int w[maxn]; 15 double p[maxn]; 16 double dp[10003]; 17 int main() 18 { 19 int T; 20 scanf("%d",&T); 21 while(T--) 22 { 23 scanf("%lf%d",&P,&n); 24 int sum=0; 25 for(int i=1;i<=n;i++) 26 { 27 scanf("%d%lf",&w[i],&p[i]); 28 sum+=w[i]; 29 } 30 P=1-P; 31 for(int i=1;i<=sum;i++) dp[i]=0; 32 dp[0]=1; 33 for(int i=1;i<=n;i++) 34 { 35 for(int j=sum;j>=w[i];j--) 36 { 37 dp[j]=max(dp[j],dp[j-w[i]]*(1-p[i])); 38 } 39 } 40 for(int i=sum;i>=0;i--) 41 { 42 if(dp[i]>P) 43 { 44 printf("%d\n",i); 45 break; 46 } 47 } 48 } 49 return 0; 50 }