Hdu 2955 Robberies//01背包

题目描述:Roy去抢银行,如何在不被抓住的情况下抢到最多的钱。给出抢每个银行能抢到的钱和被抓到的概率。

分析:刚开始以为概率只有两位小数,乘以100直接做的,结果发现数据不是这样的,果断wa了。然后一直在这里纠结,背包容量不为整数怎么办。无奈之下看一下别人的解题报告,发现可以让抢的钱看做背包容量,被抓住的概率为背包价值。(赶脚自己在死学习,o(╯□╰)o)。但是自己又想错了,直接将每次抢银行没被抓住的概率想加,懂点概率的人都知道这是很愚蠢的想法(o(╯□╰)o)。

下面是代码:

/*Hdu 2955 Robberies
   DP 0-1背包
   转移方程:f[j] = max{f[j],f[j-v]*p}
   f[j]表示抢的钱为j时的最大逃跑概率
*/
#include<iostream>
using namespace std;
const int maxn = 10005;
double p[105],f[maxn],P;
int val[105],tot;
int N;
double Max(double a,double b)
{
    return a > b ? a : b;
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        cin>>P>>N;
        tot = 0;
        for(int i = 0; i < N; i++)
        {
            cin>>val[i]>>p[i];
            tot += val[i];
        }
        for(int i = 1; i <= tot; i++) f[i] = 0;
        f[0] = 1;
        for(int i = 0; i < N; i++)
        {
            for(int j = tot; j >= val[i]; j--)
            {
                f[j] = Max(f[j],f[j-val[i]]*(1-p[i]));
            }
            //for(int k = 1; k <= tot; k++) cout<<f[k]<<" ";
            //cout<<endl;
        }
        for(int i  = tot; i >= 0; i--)
        {
            if(f[i] >= (1 - P))
            {
                //cout<<f[i]<<endl;
                cout<<i<<endl;
                break;
            }
        }
    }
    return 0;
}

之前不是很懂用一维数组为啥是按逆序来递推的,想了半天才想出了一点头绪。

    每次循环是用一维数组来储存信息,这样每次都要覆盖原来的信息。因此要在该点信息被覆盖之前更新和它有关点的信息。这样只能逆序循环了。这道题就到这里吧。

但是还是有点收获的:

一)、在做0-1背包这类题时,选好背包的容量以及物品价值。就像这道题一样。

二)、物品的价值不光可以相加,也可以相乘。就像这道题一样。

三)、转移数组的初始化问题,这也需要注意。不同的题目,初始化也不一样。

好吧,就是这样子。:-D

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值