【hdu2955】 Robberies 01背包

hdu2955 http://acm.hdu.edu.cn/showproblem.php?pid=2955

题意:盗贼抢银行,给出n个银行,每个银行有一定的资金和抢劫后被抓的概率,在给定一个概率P,表示盗贼愿意冒险抢劫所能承受的最大被抓概率。

思路:首先用1减去被抓概率,得到安全概率。那抢劫了多家银行后的安全概率就是这些银行各自的安全概率连乘起来。其实是01背包的变种,

  dp[j] 表示获得金额 j 时的安全概率。这里用滚动数组,得方程  dp[j] = max(dp[j], dp[i-a[i]]*(1-b[i])   其中a表示银行金额,b表示被抓概率。

trick:概率的精度不总是2

自WA点: 滚动数组的 j 要逆序遍历。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <cmath>
 6 #include <vector>
 7 #include <map>
 8 #include <utility>
 9 #include <queue>
10 #include <stack>
11 #define N 105
12 #define REP(i,n) for(i=0;(i)<(n);i++)
13 using namespace std;
14 const int INF=1<<30;
15 const double eps=1e-6;
16
17 double dp[N*N],b[N];
18 int n,a[N];
19
20 void run()
21 {
22     int _;
23     scanf("%d",&_);
24     while(_--)
25     {
26         int sum=0,i,j;
27         double p;
28         memset(dp,0,sizeof(dp));
29         cin>>p>>n;
30         REP(i,n)
31         {
32             cin>>a[i]>>b[i];
33             sum+=a[i];
34         }
35         dp[0]=1.0;
36         REP(i,n)
37             for(j=sum;j>=a[i];j--)
38             {
39                 dp[j]=max(dp[j],dp[j-a[i]]*(1.0-b[i]));
40             }
41         for(i=sum;i>=0;i--)
42             if(dp[i]>=1.0-p)
43             {
44                 cout<<i<<endl;
45                 break;
46             }
47     }
48 }
49
50 int main()
51 {
52 //    freopen("case.txt","r",stdin);
53     run();
54     return 0;
55 }

【hdu2955】 Robberies 01背包

时间: 2024-11-01 01:54:54

【hdu2955】 Robberies 01背包的相关文章

HDU 2955 Robberies --01背包变形

这题有些巧妙,看了别人的题解才知道做的. 因为按常规思路的话,背包容量为浮点数,,不好存储,且不能直接相加,所以换一种思路,将背包容量与价值互换,即令各银行总值为背包容量,逃跑概率(1-P)为价值,即转化为01背包问题. 此时dp[v]表示抢劫到v块钱成功逃跑的概率,概率相乘. 最后从大到小枚举v,找出概率大于逃跑概率的最大v值,即为最大抢劫的金额. 代码: #include <iostream> #include <cstdio> #include <cstring>

HDU 2955 Robberies (01背包)

Robberies Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 11297    Accepted Submission(s): 4190 Problem Description The aspiring Roy the Robber has seen a lot of American movies, and knows that

hdu 2955 Robberies 0-1背包/概率初始化

/*Robberies Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 13854 Accepted Submission(s): 5111 Problem Description The aspiring Roy the Robber has seen a lot of American movies, and knows that the

hdu 2955 Robberies (01背包好题)

Robberies Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 31769    Accepted Submission(s): 11527 Problem Description The aspiring Roy the Robber has seen a lot of American movies, and knows that

Robberies 01背包变形 hdoj

在选择物品的时候,对每种物品i只有两种选择,即装入背包或不装入背包.不能讲物品i装入多次,也不能只装入物品的一部分.因此,该问题被称为0-1背包问题. 将小偷计划要偷的钱的总数作为背包的容量,然后每个银行的存款就作为各个物品的重量, 每个银行小偷的逃跑率就作为每个物品的价值,这样就转化为01背包问题了. 至于为什么不可以用题目给的被抓获的概率作为价值,是因为小偷被抓与否的计算方法, 不是将每个银行小偷被抓的概率相乘,概率论的基本知识,所以要以逃跑率作为价值. 定义数组 F[j]为偷到j万元的时候

HDU 2955 Robberies(01 背包)

#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; struct Node { int m; double p; }; Node bank[200]; double dp[100000]; int main() { int t,n; double p; int i,j,k; scanf("%d",&am

01背包水题篇之 HDU2955——Robberies

原来是想dp[i],表示不被抓概率为i所能抢到的最大钱(概率1-100) 后来看了别人的博客是dp[i]表示抢了i钱最大的不被抓概率,嗯~,弱菜水题都刷不动. 那么状态转移方程就是 dp[i]=max(dp[i],dp[i-money]*p),初始化dp(0~maxn)为0,dp[0]=1(1毛钱都没抢你抓个毛线啊,哥是良民~) 又是贴代码环节~ <span style="font-size:18px;">#include<iostream> #include&

hdu2955 Robberies (01背包)

转载请注明出处:http://blog.csdn.net/u012860063 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2955 Problem Description The aspiring Roy the Robber has seen a lot of American movies, and knows that the bad guys usually gets caught in the end, often because t

hdu 2955 Robberies(01背包)

Robberies Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 17723    Accepted Submission(s): 6544 Problem Description The aspiring Roy the Robber has seen a lot of American movies, and knows that