您的位置:首页 > 其它

Hdu 2955 Robberies//01背包

2013-06-04 18:53 162 查看
题目描述: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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  DP 背包