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;
}
本文深入探讨了一道经典的01背包问题,涉及概率处理、数值精度、状态转移等核心概念。通过实例讲解,帮助读者理解如何将实际问题转化为算法模型,并解决复杂度较高的问题。
1万+

被折叠的 条评论
为什么被折叠?



