九度Online Judge | 题目1395:爱钱的胡老板

本文介绍了一个关于货币兑换的问题,需要通过特定金额的兑换确保获得所有类型的硬币。问题转化为一个完全背包问题的变形,并提供了解决方案的Java代码实现。
题目描述:

胡老板,别名浩帆,是九度技术组中最喜欢钱的一个,当然了,他钱肯定是没多少的,但是他唯一的乐趣也就是把玩手中不多的钱了。

胡老板难得出了趟国(当然了,也就越南老挝东南亚了,前面说了,他钱不多)。

在A国,他发现了一台自动兑换货币的机器。这时,他爱钱的兴趣又体现出来了,他想通过兑换一定数量的钱,来保证换取这个国家的所有种类的硬币。但是,这种自动兑换机的兑换策略并不知道,所以胡老板想让你帮忙计算下,是否存在这么一种可能,通过兑换一定数量的纸币,能够保证一定获取所有可能的硬币,假如存在,则只需要告诉胡老板其最小值;假如不存在,就输出-1。

例如,A国有2、5这两种面额的硬币,那么我们只需要兑换7面额的纸币即可保证获取2和5这两种面额的硬币;同样,若B国有1、2这两种面额的硬币,那我们就无能为力了,因为所有的面额,可能都是由面额为1的硬币组成。

输入:

每个测试案例包括两行:

第一行为整数N,代表硬币的种类,其中1 <= N <= 50。

第二行为N个大于0小于等于10000的整数,代表硬币的面额。注意,不同种类的硬币,面额也可能一样。

输出:

对于每个测试案例,输出一行:

若方案存在,则输出一个最小的值;若不存在,则输出-1。

样例输入:
2
2 5
2
1 2
2
1 1
样例输出:
7
-1
-1
分析:

完全背包问题的变形,一维数组记录的不是背包容量对应的最大价值,而是对应的可能组合数。

同时,还有一个过滤规则:钱币中不能出现相同数字。

个人解答:

import java.util.HashSet;
import java.util.Scanner;

public class ChangeMoney {
	private static int changeMoney(int[] m, int n) {
		HashSet<Integer> set = new HashSet<Integer>();
		int sum = 0;
		for (int i = 0; i < n; ++i) {
			if (set.contains(m[i])) {
				return -1;
			}
			set.add(m[i]);
			sum += m[i];
		}

		int[] money = new int[sum + 1];
		money[0] = 1;
		for (int i = 0; i < n; ++i) {
			for (int j = m[i]; j <= sum; ++j) {
				money[j] += money[j - m[i]];
			}
			if (money[sum] > 1) {
				return -1;
			}
		}
		return sum;
	}

	public static void main(String[] args) {
		Scanner reader = new Scanner(System.in);
		while (reader.hasNextInt()) {
			int n = reader.nextInt();
			int[] m = new int[n];
			for (int i = 0; i < n; ++i) {
				m[i] = reader.nextInt();
			}
			System.out.println(changeMoney(m, n));
		}
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值