我现在做的是第三专题编号为1022的试题,具体内容如下所示:
Problem V
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 33 Accepted Submission(s) : 15
3 0.04 3 1 0.02 2 0.03 3 0.05 0.06 3 2 0.03 2 0.03 3 0.05 0.10 3 1 0.03 2 0.02 3 0.05
2 4 6
简单题意:
一个人想到银行抢钱,但又怕被抓到,所以,他就统计了各个银行的金额和被抓的概率,得出在不被抓到的条件下能偷到的最多的钱数。
解题思路:
转化为01背包问题,在01背包中,每个物品代价是每个银行的钱的数目,物品的价值是在该银行不被抓的概率,即1-被抓概率,背包容量是所有银行钱的总和,求dp[i]表示获得i的钱不被抓的最大概率,最后从大到小枚举出dp[i]>=(1-p),这个i就是答案。
编写代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
double dp[10010];
int value[110];
double weight[110];
int nv;
void ways(int cost,double weight)
{
for(int i=nv; i>=cost; i--)
dp[i]=max(dp[i],dp[i-cost]*weight);
}
int main()
{
int t;
int nk;
double p;
scanf("%d", &t);
while(t--)
{
scanf("%lf%d",&p,&nk);
nv = 0;
for(int i=0; i<nk; i++)
{
scanf("%d%lf",&value[i],&weight[i]);
weight[i] = 1-weight[i];
nv += value[i];
}
memset(dp,0,sizeof(dp));
dp[0]=1;
for(int i=0; i<nk; i++)
ways(value[i],weight[i]);
for(int i=nv; i>=0; i--)
if(dp[i]>=1-p)
{
printf("%d\n",i);
break;
}
}
return 0;
}