ZOJ-2189

31 篇文章 0 订阅

多重背包DP,解法参见背包九讲,转化成01背包,本题数据量小,不用组合物品来优化物品总数,还有DP的时候要保存路径,因为最后要输出。这题一定要注意的是double转int的精度问题!!!参见代码, 我开始时用round方法,明明找来的所有测试数据都能过,结果提交OJ就WA。。肯定有另外的测试数据。。然后参考了大神的代码,学会了另一种转int方式。。

#include<stdio.h>
#include<limits.h>
#include<string.h>

static int min(int a, int b)
{
	return a < b ? a : b;
}

int main()
{
	double A;
	int B, C, D, E, dp[501], pack[300], path[501], res[26];
	while (scanf("%lf %d %d %d %d", &A, &B, &C, &D, &E) != EOF)
	{
		int a = (int) (A * 100.0 + 0.0001), b = min(a / 25, B), c = min(a / 10,
				C), d = min(a / 5, D), e = min(a, E);
		int i, j, index = 0;
		for (i = 0; i < b; i++)
			pack[index++] = 25;
		for (i = 0; i < c; i++)
			pack[index++] = 10;
		for (i = 0; i < d; i++)
			pack[index++] = 5;
		for (i = 0; i < e; i++)
			pack[index++] = 1;
		dp[0] = 0;
		for (i = 1; i <= a; i++)
			dp[i] = INT_MAX;
		for (i = 0; i < index; i++)
			for (j = a; j >= pack[i]; j--)
				if (dp[j - pack[i]] != INT_MAX && dp[j - pack[i]] + 1 < dp[j])
				{
					dp[j] = dp[j - pack[i]] + 1;
					path[j] = i;
				}
		if (dp[a] != INT_MAX)
		{
			memset(res, 0, sizeof(res));
			while (a)
			{
				res[pack[path[a]]]++;
				a -= pack[path[a]];
			}
			printf("%d %d %d %d\n", res[25], res[10], res[5], res[1]);
		}
		else
			puts("NO EXACT CHANGE");
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值