您的位置:首页 > 其它

HDU 2955 Robberies

2014-07-24 13:51 176 查看
题目:http://acm.hdu.edu.cn/showproblem.php?pid=2955

题意:在被抓不超过p的前提下偷得最多钱

思路:

因为概率是double,所以不能像普通背包那样,可以反过来想

w[i]表示偷第i个银行成功的概率
//输入的是偷失败的概率,所以1-w[i]

p表示成功概率下限
// 1-p

dp[i]表示偷得i钱的概率

dp[j] = max(dp[j],dp[j-v[i]]*w[i]);
//概率叠加是相乘

i从大到小遍历,第一个满足dp[i] > p条件的为结果

dp[0]初始化为1,偷0钱肯定合法

#include <stdio.h>
#include <string.h>
#define MAX 100550
double dp[MAX],w[MAX];
int v[MAX];
double max(double a,double b)
{
if(a-b>0.0000001)
return a;
return b;
}
int main()
{
int t,n,i,j,sum;
double p;
//	freopen("a.txt","r",stdin);
scanf("%d",&t);
while(t--)
{
scanf("%lf%d",&p,&n);
p = 1 - p;
sum = 0;
memset(dp,0,sizeof(dp));
dp[0] = 1;
for(i=0;i<n;i++)
{
scanf("%d%lf",&v[i],&w[i]);
w[i] = 1 - w[i];
sum += v[i];
}
for(i=0;i<n;i++)
{
for(j=sum;j>=v[i];j--)
{
dp[j] = max(dp[j],dp[j-v[i]]*w[i]);
}
}
for(i=sum;i>=0;i--)
{
if(dp[i] - p > 0.00000001)
{
printf("%d\n",i);
break;
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: