/*
HDOJ 2955
将小偷计划要偷的钱的总数作为背包的容量,然后每个银行的存款就作为各个物品的重量,
每个银行小偷的逃跑率就作为每个物品的价值,这样就转化为01背包问题了。
至于为什么不可以用题目给的被抓获的概率作为价值,是因为小偷被抓与否的计算方法,
不是将每个银行小偷被抓的概率相乘,概率论的基本知识,所以要以逃跑率作为价值。
定义数组 F[j]为偷到j万元的时候,逃跑的概率,那么状态方程如下:
F[j]=max{F[j],F[j-m[i]]*g[i]},其中m[i]是第i个银行的存款,g[i]是在该银行偷窃后逃跑的概率
这个状态方法和O1背包的状态方程是一个思想的。
*/
#include <iostream>
using namespace std;
int main()
{
int T,n,sum,m[101],i,j;
double p,f[100100],g[101],temp;
cin>>T;
while(T--)
{
sum=0;
memset(f,0,sizeof(f));
f[0]=1; //没偷钱当然可以 100% 不被抓
cin>>p>>n;
for(i=0;i<n;i++)
{
cin>>m[i]>>temp;
g[i]=1-temp;
sum += m[i];
}
//核心代码,DP所在
for(i=0;i<n;i++)
{
for(j=sum;j>=m[i];j--)
if(f[j-m[i]]*g[i] > f[j])
f[j]=f[j-m[i]]*g[i];
}
p=1-p;
//从后面找起,最大的一个逃跑率大于给定的逃跑率的就是答案
for(i=sum;i>=0;i--)
if(f[i] >= p)
break;
cout<<i<<endl;
}
return 0;
}
01背包——HDOJ 2955
最新推荐文章于 2020-02-24 17:06:57 发布