HDU 2955 Robberies【01背包】
来源:互联网 发布:批量上传淘宝宝贝软件 编辑:程序博客网 时间:2024/06/04 18:44
source:
点击打开链接
题意:说强盗要去几个银行偷盗,已知各个银行的钱数和被抓的概率,以及强盗能容忍的最大的被抓概率。求他在被抓概率小于容忍值的情况下最多能偷到多少钱?
思路:第一反应:01背包,将每个银行当物品,钱数作为价值,被抓概率做容量。但这有问题,被概率不能当做容量,因为被抓概率并非简单的相加,而是要转化为不被抓概率相乘再用1减,于是这就不好写出递推关系了!于是换种思路,这种问题还是得01背包,只是将价值和容量换一换,将抢到的总钱数作为容量,不被抓的概率作为价值,这样就有:dp[i][j]=前i个银行中,抢到的总价值不大于j的最大不被抓的概率
写出原递推公式比较好理解:dp[i][j]=max(dp[i-1][j],dp[i-1][j-m[i]]×(1-p[i]));
进行空间优化后:从sum(所有m[i]之和)到m[i]倒着循环:dp[j]=max(dp[j],dp[j-m[i]]×(1-p[i]))
以上就算出了不大于某给定抢钱总数的情况下不被抓的概率,最后只需从sum依次往小处找,第一个是的不被抓概率大于等于1-P值时即为最大钱数!
代码如下:
#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;int m[105];double p[105],dp[10010];int main(){ int T,n,sum; double P; scanf("%d",&T); for(int t=0;t<T;t++) { scanf("%lf%d",&P,&n);//printf("%lf\n",P); sum=0; for(int i=0;i<n;i++) { scanf("%d %lf",&m[i],&p[i]); sum+=m[i]; } memset(dp,0.0,sizeof(dp)); dp[0]=1; for(int i=0;i<n;i++) for(int j=sum;j>=m[i];j--) dp[j]=max(dp[j],dp[j-m[i]]*(1-p[i])); //dp[j]:目前总价值不大于j的最大不被抓的概率 for(int i=sum;i>=0;i--) if(dp[i]>=(1-P)) { printf("%d\n",i); break; } } return 0;}
阅读全文
0 0
- hdu 2955 01 背包 Robberies
- hdu 2955 Robberies--01背包
- Hdu 2955 Robberies//01背包
- hdu 2955 Robberies (01背包)
- hdu 2955 Robberies 01背包
- HDU 2955 Robberies(01背包)
- HDU 2955 Robberies (01背包)
- hdu 2955 Robberies(01背包)
- hdu 2955 Robberies(01背包)
- hdu Robberies 2955 01背包
- HDU 2955 - Robberies(01 背包)
- HDU--2955--Robberies--01背包
- hdu-2955-01背包-Robberies
- HDU 2955 Robberies 01背包
- HDU 2955Robberies(01 背包)
- HDU - 2955 Robberies 01背包
- HDU-2955-Robberies【01背包】
- HDU 2955 Robberies 【01背包】
- [Noi2013]快餐店
- java注解,@,注解有什么用
- Java String Source Code
- ubuntu下修复不能访问分区问题
- 图的储存
- HDU 2955 Robberies【01背包】
- 技术文章 | JAVASCRIPT作为功能编程介绍
- Linux学习之路
- Maven学习总结(八)——使用Maven构建多模块项目
- 读书笔记_重构,改善既有代码的设计
- 前端基础之html
- ios 开发推荐
- Counting Bits问题及解法
- NSBundle