• 找零问题


    问题描述:

    给定总金额为n(n为正整数)和若干面值为d1=1<d2<d3<...<dj...<dm的硬币(硬币数量无限),求用最小的硬币数凑足金额n的方案。

    注:如果n<d1,那么无法用现有的硬币面值找零,为规避这种情况,假定n>=d1;d1=1能够保障任何正整数n都能被准确的找零。

    分析:

    为了验证其最优子结构的性质,可以这样考虑:

    为了求解问题规模为n的最小硬币数量C(n),向前思考一步,C(n)实际上可以认为是从问题规模为n-dj(满足d1<=dj<=n)的基础上在选取面值为dj的硬币而来。求解C(n)只需要求解所有满足条件的子问题n-dj中最小的C(n-dj),那么,C(n)在最小的C(n-dj)基础上加1即可。

    其递推关系为:

    动态规划实现:

        /*
         * 动态规划实现
         * */
        public static int changeOfLessCoins(int[] ary,int n){
            int m = ary.length;
            int[] aux = new int[n+1];//aux[0]充当哨兵,没事实际含义
            int tmpLest;
            for (int i = 1; i <= n; i++) {
                tmpLest = Integer.MAX_VALUE;
                for (int j = 0; j < m; j++) {
                    if (i>=ary[j]) {
                        tmpLest = Math.min(aux[i-ary[j]], tmpLest);//目的在于找出一个最小的tmpLess
                    }
                }
                aux[i] = tmpLest+1;
            }
            return aux[n];
        }

    贪心算法实现:

        /*
         * 贪心算法实现
         * */
        public static int changeOfLessCoins(int[] ary,int n){
            int length = ary.length;
            int count  = 0;
            while(n>0){
                for (int i = length-1; i >= 0; i--) {//每次从最大的面值开始选择
                    if (ary[i]<=n) {
                        n -= ary[i];
                        count++;
                        break;
                    }
                }
            }
            return count;
        }

    与找零问题类似的还有像完美平方问题

    给定一个正整数N,用最少的平方数(1,4,9,26,25...)使得其和等于N。

    比如N=13,最少的平方数为13=4+9,只需要4和9两个平方数即可。

    参考资料:

    算法按设计与分析基础.第三版.第十五章

  • 相关阅读:
    MAC mysql安装及设置
    Mac下php连接mysql数据库失败解决办法
    Mac Yosemite OS10.10 Apache 虚拟主机设置
    《深入理解JavaScript》——Day1
    《JavaScript设计模式》读书笔记——Day3
    《JavaScript设计模式》读书笔记——Day2.1
    《JavaScript设计模式》读书笔记——Day2
    《JavaScript设计模式》读书笔记——Day1
    随笔,记录JavaScript中的面试题
    《JavaScript权威指南》学习笔记——Day3
  • 原文地址:https://www.cnblogs.com/qcblog/p/7784080.html
Copyright © 2020-2023  润新知