题目:
就是一个小偷要去偷银行,然后给你他可以容忍的最大被抓率,和有多少个银行,之后给你每个银行的钱数和逃跑率,之后问你他可以获得的最大钱数是多少。
解析:
把钱数当做总的体积,把逃跑了当做价值,就是一个01背包问题;
状态转移方程为:dp[j]=max(dp[j],dp[j-v[i]]*(1.0-w[i]));
代码:
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#include<algorithm>
const double PI=acos(-1);
using namespace std;
int v[1005];
double w[1005];
double dp[10005];
int main()
{
int t,i,j,m;
double n;
scanf("%d",&t);
while(t--)
{
int sum=0;
scanf("%lf%d",&n,&m);
for(i=0;i<m;i++)
{
scanf("%d",&v[i]);
scanf("%lf",&w[i]);
sum+=v[i];
}
memset(dp,0,sizeof(dp));
dp[0]=1;
for(i=0;i<m;i++)
{
// 多重背包 for(int k = 0;k < b[i];k++)
for(j=sum;j>=v[i];j--) //为完全背包时,j=0;j<=m;j++;
{
dp[j]=max(dp[j],dp[j-v[i]]*(1.0-w[i]));
}
}
for(j=sum;j>=0;j--)
{
if(dp[j]>=(1.0-n))
{
printf("%d\n",j);
break;
}
}
}
return 0;
}