3,5,10面值的硬币换取N有多少种方法

package com.cgx.datastructure.pro;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class DPChangeCoin {
    /** 换取目标 n */
    private int n;
    /** 硬币数量 m */
    private int m;
    /** 面值 */
    private int[] val;
    /** 换取的次数 */
    private int count;
    /** 多个目标被换取的次数 */
    private List<String> result;

    public DPChangeCoin(int n, int m, int[] val) {
        this.n = n;
        this.m = m;
        this.val = val;
        this.result = new ArrayList<>();
    }

    /**
     * 计算过程
     *
     */
    private int cal() {
        int[] dp = new int[n + 1];
        // 每个硬币数值本身的次数
        dp[0] = 1;
        for (int i = 0; i < m; i++) {
            for (int j = val[i]; j <= n; j++) {
                // 目标与硬币面值相差多少
                int diff = j - val[i];
                // 相差的值是否能够被换取
                int can = dp[diff];
                // 该目标能够被换取的次数
                dp[j] += can;
            }
            result.add(Arrays.toString(dp));
        }
        return dp[n];
    }

    /**
     * 计算结果
     *
     */
    public int getCount() {
        return count = cal();
    }

    /**
     * 打印计算过程
     *
     */
    public void printResult() {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < m; i++) {
            if (i == 0) {
                sb.append("{ ").append(val[i]).append(" }");
            } else {
                sb.delete(sb.indexOf("}"), sb.length());
                sb.append(", ").append(val[i]).append(" }");
            }
            sb.append(" - ").append(result.get(i));
            System.out.println(sb.toString());
        }
    }
}
package com.cgx.datastructure.pro;

public class DPTest {
    public static void main(String[] args) {
        int[] a = {3, 5, 10};
        int n = 10;
        int m = 3;
        DPChangeCoin cp = new DPChangeCoin(n, m, a);
        int total = cp.getCount();
        System.out.println("total: " + total);
        cp.printResult();
    }
    /**out
     total: 2
     数组里面的index为目标,value为该面值可以换取的次数
     { 3 } - [1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0]          表示:用3可以换取的目标的次数
     { 3 , 5 } - [1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1]      表示:用3、5可以换取的目标的次数
     { 3 , 5 , 10 } - [1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 2] 表示:用3、5、10可以换取的目标的次数
     */
}

 

posted @ 2022-01-13 12:30  黎明的星海  阅读(58)  评论(0编辑  收藏  举报