hdu 2955 Robberies 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2955
题目大意:劫匪Roy the Robber打算大干一票然后安度晚年,估计了n个银行的储备金总数,及其被抓概率(抢一次必然就全抢走,然后就要承担在这个银行被抓的危险了)。其母有些担心,给规定了个最大被抓概率忍受上限,我们要做的事,就是求出在这个上限下能抢的最多钱数。
题目分析:0-1背包,按照常规思想,是要把概率当作重量,钱当作价值的。但小数显然不能作为下标,所以要另寻他法。网上的做法是把安全概率(1-被抓概率)作为价值(叠加方式为相乘),整型的钱数作为重量(可作下标)。而后自上而下遍历背包找到第一个安全概率符合要求的点,输出其下标,就是答案。
code:
#include<stdio.h>
#include<math.h>
#include<string.h>
double max(double a,double b)
{
return a>b?a:b;
}
struct node
{
int v;
double w;
} a[200];
int main()
{
int t,i,j,n,sum;
double tp,temp,dp[30000];
//freopen("2.txt","r",stdin);
scanf("%d",&t);
while(t--)
{
sum=0;
scanf("%lf%d",&tp,&n);
tp=1-tp;
memset(dp,0,sizeof(dp));
for(i=0; i<n; i++)
{
scanf("%d%lf",&a[i].v,&temp);
sum+=a[i].v;
a[i].w=1-temp;
}
for(i=0,dp[0]=1; i<n; i++)
{
for(j=sum; j>=a[i].v; j--)
{
dp[j]=max(dp[j],dp[j-a[i].v]*a[i].w);
}
}
for(i=sum;i>=0;i--)
{
if(dp[i]>=tp)
{
printf("%d\n",i);
break;
}
}
}
return 0;
}
PS:居然被01背包难住了,将近两天解出此题,sading……