HDU 2955

来源:互联网 发布:阿里云合作伙伴 logo 编辑:程序博客网 时间:2024/06/05 08:43

题目描述是一个汉子准备去抢劫,给定n个银行的存款和风险,求让他在能承受的风险下取得最大利益。

思路 

01背包

如果按照普通01背包的思路来想的话容量应该是风险,价值是利益。但是容量因为是浮点数所以转移并不简单,所以我们可以

计算出所有可能获得利益的概率。把容量改为利益,价值是风险,这样便能转移状态。这样就相当于求获得最大利益的最小风

险,但是计算最小风险的话用概率的知识就知道,每抢劫一个银行最小风险计算的方法复杂,但是反面就容易的多,要求不被

抓住的几率,用乘法即可,这样计算的便是最大不被抓风险。

#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>using namespace std;const int maxn =100 + 10;int m[maxn];double p[maxn];double d[maxn * maxn];int main(){    int T; scanf("%d", &T);    while(T --){        int n; double x;        scanf("%lf%d", &x, &n);        int sum = 0;        for(int i = 0; i < n; ++i) {            scanf("%d %lf", &m[i], &p[i]);            p[i] = 1 - p[i];            sum += m[i];        }        memset(d, 0, sizeof(d));        d[0] = 1;        for(int i = 0; i < n; ++i)            for(int j = sum; j >= m[i]; --j) {                d[j] = max(d[j], d[j - m[i]] * p[i]);            }        int i;        for(i = sum; i >= 0; --i) {            if(d[i] >= 1 - x) break;        }        printf("%d\n", max(i, 0));    }    return 0;}

0 0
原创粉丝点击