hdu2955背包问题

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

题意是一个小偷去偷N家银行,给一个被抓到的概率标准,然后给出每家银行能偷的钱和被抓的概率,求在不被抓的情况下最多能偷到多少钱?

将F(i)表示偷i元钱的最大安全概率,然后就是一个01背包问题,状态转移方程式F(i)=max{F[i],F[i-money[j]]*(1-p[j])}

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int m[110];
float p[110],f[10010];
int main()
{int t;
//freopen("E:\\in.txt","r",stdin);
cin>>t;
while(t--)
{memset(f,0,sizeof(f));
f[0]=1;
    int n;
float pm;//状态转移方程f[i]=max{f[i],f[i-m[j]]*(1-p[j])}
    scanf("%f%d",&pm,&n);
    int sum=0;
    for(int i=0;i<n;i++)
    {
        scanf("%d%f",&m[i],&p[i]);
        sum+=m[i];//sum为一共有多少钱
    }
    int i,j;
       for(i=0;i<n;i++)//01背包的两层循环,有n家银行,这边的钱相当于背包容量
        for(j=sum;j>=m[i];j--)
            if(f[j]<f[j-m[i]]*(1-p[i]))
            f[j]=f[j-m[i]]*(1-p[i]);
        for(i=sum;i>=0;i--)
        if(f[i]>=1-pm)
        {
            printf("%d\n",i);
            break;
        }
}
    return 0;
}


在01背包中,有两种做法。

一种是二维数组dp[i][j]表示前i件物品放入容积为j的背包中的最大价值,那么对于第i件物品,它只有放与不放两种选择,那么状态转移方程就是    dp[i][j]=max{dp[i-1][j],dp[i-1][j-v[i]]+value[i]}   ,,如果放的话就考虑前i-1件物品放入容积为扣掉第i件物品体积的最大价值,不放的话最大价值就是讲i-1件物品放入j体积的最大价值

实现方法是

两层循环,外层1到N表示选哪个物品,内层循环从0到V,先判断下当前的V是否放得下当前物品,然后开始状态转移。

还有一种就是只用一维数组,也就是上题的方法,f[j]表示放入容量为J的物品的最大价值,然后外层循环和第一种一样从0到N,但是内层是从V到当前体积,因为是从后往前推的,状态转移方程式

f[j]=max{f[j],f[j-volume[i]]+value[i]};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值