HDU 2955

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


“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值