这题要先这样想,把每个银行的钱看作是代价,而不被抓住的概率是价值!这样就简单多了,直接01背包搞起,其实01背包的代码都是差不多,只不过是有些地方要改变,而且做01背包问题主要是找到谁是代价,谁是价值!这样就直接套公式了!
#include<stdio.h>
#include<iostream>#include<string.h>
#include<algorithm>
using namespace std;
double dp[10010];
int value[105];
double weight[105];
int sum;
void zeroonepack(int cost,double weight)
{
int i;
for(i=sum;i-cost>=0;i--)
dp[i]=max(dp[i],dp[i-cost]*weight);//状态转移方程,那为什么是*weight呢?因为这个是要根据题目来看是怎样把价值算上去!
}
int main()
{
int t,n,m,i;
double p;
scanf("%d",&t);
while(t--)
{
scanf("%lf%d",&p,&n);
sum=0;
for(i=0;i<n;i++)
{
scanf("%d%lf",&value[i],&weight[i]);
weight[i]=1-weight[i];//这里就是得到不被抓到的概率!也就是所谓的价值!不可忘记
sum+=value[i];
}
memset(dp,0,sizeof(dp));//这个要记住清0
dp[0]=1;
for(i=0;i<n;i++)
zeroonepack(value[i],weight[i]);
for(i=sum;i>=0;i--)//从最大的开始找,这样速度快!
{
if(dp[i]>=1-p)//刚好偷了多少钱时就刚好没有被抓住!
{
printf("%d\n",i);
break;
}
}
}
return 0;
}