动态规划专题(01背包)HDU 2955-Robberies

来源:互联网 发布:淘宝一分钱群 编辑:程序博客网 时间:2024/06/04 19:10

题目链接:

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

思路分析:

一开始看到这道题,我以为只是简单的把01背包问题背包容量换成了小数,因为我以为抢两家银行被抓概率是各自被抓概率之和,所以我把被抓概率*10000看做可选物品的花费,把最大容许被抓概率看做背包容量。结果样例是过了,提交wa了好多发。后来才意识到被抓概率应该是1-安全概率,而安全概率是抢银行各自安全概率的乘积。都是概率学没学好的锅。

弄明白以上内容之后,把所获金额作为重量,把安全概率看做价值,状态转移方程为:

dp[i][j]=max(dp[i-1][j],dp[i-1][j-p[i]]*w[i])

上式中,p[i]表示抢第i家银行所获金额,w[i]表示抢第i家银行安全概率。

代码实现:

#include"cstdio"#include"algorithm"#include"cstring"using namespace std;int T;int N;double W;double w[105];int p[105];double dp[10005];int main(){    scanf("%d",&T);    while(T--)    {        memset(dp,0,sizeof(dp));        scanf("%lf%d",&W,&N);        W=1-W;        int Maxc=0;        for(int i=1;i<=N;i++)        {            scanf("%d%lf",&p[i],&w[i]);            w[i]=1-w[i];            Maxc+=p[i];        }        for(int i=0;i<=N;i++)        {            dp[0]=1;        }        for(int i=1;i<=N;i++)        {            for(int j=Maxc;j>0;j--)            {                dp[j]=max(dp[j-p[i]]*w[i],dp[j]);            }        }        for(int i=Maxc;i>=0;i--)        {            if(dp[i]>W)            {                printf("%d\n",i);                break;            }        }    }    return 0;}

0 0
原创粉丝点击