HDU2955 Robberies 01背包

题目大意:Roy要抢劫银行,每抢一个银行都有一定的被抓概率,现在给你一个安全概率,以及每个银行的库存现金和抢劫该银行被抓的概率,问你在安全概率的情况下Roy最多可以抢劫多少现金。

乍一看是背包问题,其实就是背包问题,只要稍微变形一下就行了,可以看出,本题中安全概率是背包的容量,每个银行的被抓概率是质量,但这样肯定是行不通的,因为我们要用dp[ i ]数组来纪录质量为i时的最大价值,那么质量显然要为整数才行,所以我们可以把问题反过来看,把每个银行的库存现金看做是质量,那么所有银行的库存现金总数就是背包的容量了,每个银行被抓的概率就可以看做是每件物品的价值了,这样问题便迎刃而解了。

状态转移方程:dp(i,sum)=max(dp(i-1,sum),dp(i-1,sum-w[ i ])*(1-p[ i ] ));

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
typedef struct node
{
    int m;
    double p;
}Bag;
Bag bag[110];
double dp[11000];
int main()
{
    int t,n,sum;
    int i,j;
    double pro;
    cin>>t;
    while(t--)
    {
        sum=0;
        scanf("%lf%d",&pro,&n);
        for(i=1;i<=n;i++)
        {
            scanf("%d%lf",&bag[i].m,&bag[i].p);
            sum+=bag[i].m;
        }
        memset(dp,0,sizeof(dp));
        dp[0]=1;
        for(i=1;i<=n;i++)
          for(j=sum;j>=bag[i].m;j--)
            dp[j]=max(dp[j],dp[j-bag[i].m]*(1-bag[i].p));
        for(i=sum;i>=0;i--)
            if(dp[i]>1-pro)
            {
                printf("%d\n",i);
                break;
            }
    }
    return 0;
}


你可能感兴趣的:(HDU2955 Robberies 01背包)