HDU 2955
这道题目十分的经典。是一个01背包问题,但又高于十分基础的01背包。
首先,这里面使用了概率double类型,所以便不能使用它作为w,c。当时第一眼看到这道题目的时候,我就犯了一个十分不应该犯得错误。当时把概率都×100,double类型,精度不止0.01。
第二,这道题目需要转换,就是把银行偷来的钱数,作为dp下标,不被抓的概率,为dp[i]。
第三,输出的时候转换,在满足条件下,不被抓,dp下标最大的情况输出。
第四,我这里调用了函数超时了,所以把背包问题的核心代码放入了主函数中。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
double dp[10001] = {0};
int mj[101] = {0};
double pj[101] = {0};
int main(void)
{
int i, j, sum, t, n;
double p;
scanf("%d", &t);
while( t-- )
{
memset(dp, 0, sizeof(dp));
scanf("%lf %d", &p, &n);
for(i = 1,sum = 0; i <= n; i++)
{
scanf("%d %lf", &mj[i], &pj[i]);
sum += mj[i];
}
dp[0] = 1;
for( i = 1; i <= n; i++)
for( j = sum; j >= mj[i]; j--)
if(dp[j] < dp[j - mj[i]] * (1 - pj[i]))
dp[j] = dp[j - mj[i]] * (1 - pj[i]);
for(i = sum; i >= 0; i--)
{
if(dp[i] >= (1 - p))
{
printf("%d\n", i);
break;
}
}
}
return 0;
}