问题描述:想兑换100元零钱,有1元、2元、5元和10元四种面值,总共有多少况换方法?
解题思路:1的数量范围:0--x;2的数量范围:0--x/2;同理5:0--x/5; 10: 0--x/10。 f(x):从大到小考虑,先确定含有10的个数i, 然后求f(x - 10 * i),此时10的个数已经确定,只考虑还未确定的 5,2,1即可。10的数量范围是:0--x/10,循环启遍历。其他数值易是如此。当10,5,2的数量都确定之后,剩余的部分全由面值为1的硬币来兑换,1的数量等于此时的x即可。
代码如下:
import java.util.ArrayList; import java.util.List; /** * Created by on 2017/8/22. * 想兑换100元零钱,有1元、2元、5元和10元四种面值,总共有多少况换方法? * * 解题思路:1的数量范围:0--x;2的数量范围:0--x/2;同理5:0--x/5; 10: 0--x/10 * f(x):从大到小考虑,先确定含有10的个数i, 然后求f(x - 10 * i),此时10的个数已经确定,只考虑还未确定的 5,2,1即可。 * 10的数量范围是:0--x/10,循环启遍历。其他数值易是如此。当10,5,2的数量都确定之后,剩余的部分全由面值为1的硬币来兑换, * 1的数量等于此时的x即可。 */ public class ExchangeCoins { public static int count = 0; //public static int[] ns = new int[4]; public static List<int[]> list = new ArrayList<int[]>(); public static void main(String[] args) { exchangeCoins(8, -1, -1, -1, -1); for(int i = 0; i < list.size(); i++) { for(int n : list.get(i)) { System.out.print(n + "\t"); } System.out.println(); } System.out.println(count); } /** * 兑换硬币 * @param x * @param n10 10的数量 * @param n5 5的数量 * @param n2 2的数量 * @param n1 1的数量 */ public static void exchangeCoins(int x, int n10, int n5, int n2, int n1) { if(n10 < 0) { for(int i = 0; i < x/10 + 1; i++) { exchangeCoins(x - 10 * i, i, n5, n2, n1); } }else if(n5 < 0) { for(int i = 0; i < x/5 + 1; i++) { exchangeCoins(x - 5 * i, n10, i, n2, n1); } }else if(n2 < 0) { for(int i = 0; i < x/2 + 1; i++) { exchangeCoins(x - 2 * i, n10, n5, i, n1); } }else { n1 = x; int[] ns = new int[4]; ns[0] = n1; ns[1] = n2; ns[2] = n5; ns[3] = n10; for(int i = 0; i < ns.length; i++) { if(ns[i] < 0) { ns[i] = 0; } } list.add(ns); count = count + 1; } } }