首页 > 代码库 > (背包dp)HDU - 2955 Robberies
(背包dp)HDU - 2955 Robberies
原题链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=2955
(可能失效)
题意:小偷抢劫n个银行,每个银行有两个属性,m为拥有的库存金额,p为小偷偷这个银行被抓的概率。小偷抢银行的总被抓概率不能超过V。求最多抢到的金额。
分析:这题拿到手很容易想到把概率*100,以总概率V为背包容积,以抢到的金额为价值跑01背包。
但是确实本题坑之所在。WA了好多发。
看了大神博客才明白,这里需要一个转化,直接跑以总金额sum为容积,不被抓的概率为价值的背包,最后一波循环求出所得金额最大,1-不被抓概率>=总被抓的概率V就行了。
注意点:求不被抓的概率时候要*,而不是+,之前很智障的写了个+。。因为要*,需要处理边界,dp[0]=1。
代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cmath> 5 #include<cstring> 6 #include<set> 7 #include<vector> 8 #include<queue> 9 #include<map>10 #include<list>11 #include<bitset>12 #include<string>13 #include<cctype>14 #include<cstdlib>15 16 using namespace std;17 18 typedef long long ll;19 typedef unsigned long long ull;20 21 int t;22 double V;23 int n;24 const int maxn=10010;25 double v[110];26 int m[100];27 double dp[maxn];28 29 void solve() {30 scanf("%d",&t);31 while(t--){32 memset(dp,0,sizeof(dp));33 scanf("%lf%d",&V,&n);34 int sum=0;35 for(int i=0;i<n;i++){36 scanf("%d%lf",&m[i],&v[i]);37 sum+=m[i];38 }39 dp[0]=1;40 for(int i=0;i<n;i++){41 for(int j=sum;j>=m[i];j--){42 dp[j]=max(dp[j],dp[j-m[i]]*(1-v[i]));43 }44 }45 int i;46 for(i=sum;1-dp[i]>=V;i--);47 printf("%d\n",i);48 }49 }50 51 52 53 int main() {54 55 #ifndef ONLINE_JUDGE56 freopen("in.txt", "r", stdin);57 //freopen("out.txt", "w", stdout);58 #endif59 //iostream::sync_with_stdio(false);60 solve();61 return 0;62 }
(背包dp)HDU - 2955 Robberies
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。