HDU 2955

HDU 2955

这道题目十分的经典。是一个01背包问题,但又高于十分基础的01背包。

首先,这里面使用了概率double类型,所以便不能使用它作为w,c。当时第一眼看到这道题目的时候,我就犯了一个十分不应该犯得错误。当时把概率都×100,double类型,精度不止0.01。

第二,这道题目需要转换,就是把银行偷来的钱数,作为dp下标,不被抓的概率,为dp[i]。

第三,输出的时候转换,在满足条件下,不被抓,dp下标最大的情况输出。

第四,我这里调用了函数超时了,所以把背包问题的核心代码放入了主函数中。

#include 
#include 
#include 
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;
}


你可能感兴趣的:(ACM水题之路)