找零钱问题-图的深度优先

来源:互联网 发布:杀手僵尸之城2mac破解 编辑:程序博客网 时间:2024/05/16 01:32

题目

这是今年华为校招的一道测试题,题目为:
我们知道人民币有1、2、5、10、20、50、100这几种面值。现在给你n(1≤n≤250)元,让你计算换成用上面这些面额表示且总数不超过100张,共有几种。比如4元,能用4张1元、2张1元和1张2元、2张2元,三种表示方法。

思路

根据{1、2、5、10、20、50、100}构建一张 n行7列的图,利用图的深度优先收索算法求解。

代码:

import java.util.ArrayList;import java.util.Collections;import java.util.HashSet;public class Main {    public static void main(String[] args) {        Main main = new Main();        int[] a = { 1, 2, 5, 10, 20, 50, 100 };        int n = 5;        main.f1(a, n);    }    private void f1(int[] a, int n) {        if (n <= 0) {            System.out.println(0);            return;        }        HashSet<String> arr = new HashSet<String>();        ArrayList<Integer> list = new ArrayList<Integer>();        getResult(a, n, 0, arr, list);        System.out.println("共有:" + arr.size() + "种\n分别是:");        for (String str : arr) {            System.out.println(str);        }    }    private void getResult(int[] a, int n, int sum, HashSet<String> arr,            ArrayList<Integer> list) {        if (sum > n) {            return;        }        if (sum == n && arr.size() <= 100) {            StringBuffer sb = new StringBuffer();            Collections.sort(list); // 排序去重            for (int i = 0; i < list.size(); i++) {                sb.append(list.get(i) + " ");            }            arr.add(sb.toString());            return;        }        for (int i = 0; i < a.length; i++) {            sum += a[i];            list.add(a[i]);            // 深度优先            getResult(a, n, sum, arr, list);            // 回溯            sum -= a[i];            list.remove((Object) a[i]);        }    }}

结果:

共有:4种分别是:1 1 1 1 1 1 2 2 5 1 1 1 2 
0 0
原创粉丝点击