Robberies (01背包dp变形)

原文链接: http://www.cnblogs.com/sykline/p/9737861.html

题意:一个强盗要抢劫银行又不想被抓到,所以要进行概率分析求他在不被抓的情况下能抢最多的钱。他给定T(样例个数),N(要抢的银行的个数),P(被抓的概率要小于P)Mj(强盗能抢第j个银行Mj元钱),Pj(强盗抢第j个银行被抓的概率为Pj)。

思路:被抓的概率不好直接求出来,但可以直接求出不被抓的概率,则有状态转移方程dp[j] = max(dp[j], dp[j-b[i].money]*b[i].p)表示抢到j元钱被抓的最大的概率是多少。然后逆序遍历第一个小于P的dp的下标就是答案。

PS:数组的下标表示的是可以抢到的钱数,所以不能按100来开数组。。。。。。。。(T到吐血)

代码:

 1 #include <iostream>
 2 #include <queue>
 3 #include <cstdio>
 4 #include <algorithm>
 5 #include <cmath>
 6 #include <cstring>
 7 #include <queue>
 8 #include <map>
 9 #include <vector>
10 #define INF 0x3f3f3f3f
11 #define FRE() freopen("in.txt","r",stdin)
12 
13 using namespace std;
14 typedef long long ll;
15 const int maxn = 10000;
16 double dp[maxn];
17 struct Bank
18 {
19     int money;
20     double p;
21 } bb[maxn];
22 
23 int main()
24 {
25     ios::sync_with_stdio(false);
26     int T,n;
27     double p;
28     cin>>T;
29     while(T--)
30     {
31         int sum = 0;
32         cin>>p>>n;
33         for(int i = 0; i<n; i++)
34         {
35             cin>>bb[i].money>>bb[i].p;
36             sum += bb[i].money;
37         }
38         memset(dp,0,sizeof(dp));
39         dp[0] = 1;
40         for(int i = 0; i<n; i++)
41         {
42             for(int j=sum; j>=bb[i].money; j--)
43             {
44                 dp[j] = max(dp[j], dp[j-bb[i].money]*(1.0 - bb[i].p));
45             }
46         }
47         int ans = 0;
48         for(int i = sum; i>=0; i--)
49         {
50             if(1-dp[i]<=p)
51             {
52                 ans = i;
53                 break;
54             }
55         }
56         cout<<ans<<endl;
57     }
58     return 0;
59 }
View Code

转载于:https://www.cnblogs.com/sykline/p/9737861.html

猜你喜欢

转载自blog.csdn.net/weixin_30701575/article/details/94789335
今日推荐