您的位置:首页 > 其它

hdoj2955 Robberies(01背包)

2017-12-10 17:14 288 查看

题目链接

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

题意

有n家银行,每家银行有两个属性:钱数m,概率p,p表示抢这家银行被逮着的概率。有一个人想抢银行,他认为只要在他抢一些银行后,被逮着的概率(指抢完所有银行被逮着的概率)小于pm就可以抢,求这个人最多可以抢多少钱。

思路

01背包问题,这题要注意钱数是背包容量,成功逃走的概率为价值(如果反过来会发现代码没办法写,因为反过来数组dp下标为小数)。数组dp[i]表示在抢的钱数为i的情况下,成功逃走概率的最大值。求出成功逃走概率的最大值后,1-最大值即为被逮着概率的最小值,再拿最小值与pm比较即可。此外还要注意dp数组的初始化。

代码

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;

const int N = 110;
const int M = 100 * 100 + 10;
double p
;
int m
;
double dp[M];

int main()
{
//freopen("hdoj2955.txt", "r", stdin);
int t, n;
double pm;
cin >> t;
while (t--)
{
int sum = 0;
cin >> pm >> n;
for (int i = 0; i < n; i++)
{
cin >> m[i] >> p[i];
p[i] = 1 - p[i];    //成功逃走的概率
sum += m[i];
}

memset(dp, 0, sizeof(dp));
dp[0] = 1;    //没有抢钱,成功逃走的概率为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]] * p[i]);
}

for (int i = sum; i >= 0; i--)
if (1 - dp[i] < pm)
{
cout << i << endl;
break;
}
}
return 0;
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: