常考经典算法---动态规划(拼凑面额、背包问题)

<1>拼凑面额

给你六种面额1、5、10、20、50、100元的纸币,假设每种币值的数量都足够多,编写程序求组成N员(N为0-10000的非负整数)的不同组合的个数。 

输入描述:

输入为一个数字N,即需要拼凑的面额

输出描述:

输出也是一个数字,为组成N的组合个数。

示例1

输入

5

输出

2

链接:https://www.nowcoder.com/questionTerminal/14cf13771cd840849a402b848b5c1c93
来源:牛客网

/*动态规划
    
需要拼凑的面额是n,
    
维护dp[i],表示取到i时的组合数目,dp[0]=1,
    
面额数组a[6]={1,5,10,20,50,100},
    
dp[j]=dp[j]+dp[j-a[i]],约数条件j>a[i]。
    
因为面额数目任意,所以需要分别处理只有面额1时,
    
组合钱数为1~n的各自组合数dp[1]~dp[n],
    
然后有面额1,5时,组合钱数为1~n的各自组合数dp[1]~dp[n],
    
依此内推。。。详情见程序。
*/

链接:https://www.nowcoder.com/questionTerminal/14cf13771cd840849a402b848b5c1c93
来源:牛客网

一个典型的dp问题,参照了大神的思路加上百度dp思想,总结一下: 1.dp概念:简单来说就是将原来的问题分解成多个子问题,然后将子问题一个一个的解决,最终问题的规模变小了; 2.本题可以使用dp的思想来做,合成一个面值为n的组合数,可以看成合成n-1,n-5,n-10,n-20,n-50,n-100五个面值的组合数之和,然后将问题细分化,最终可以求出结果,其中我们知道,面值为1的组合数为1 贴代码:

链接:https://www.nowcoder.com/questionTerminal/14cf13771cd840849a402b848b5c1c93
来源:牛客网

import java.util.Scanner;
 
public class StringUtil {
 
    //拼凑面额
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int arr[] = {1,5,10,20,50,100};
        while(in.hasNext()){
            int n = in.nextInt();
            long res[] = new long[n+1];
            res[0] = 1L;
             
            for(int i=0; i<arr.length; i++){
                for(int j=1; j<=n; j++){
                    if(j >= arr[i]){
                        res[j] += res[j-arr[i]];
                    }
                }
            }
             
            System.out.println(res[n]);
        }
    }
}

    原文作者:动态规划
    原文地址: https://blog.csdn.net/qq_31881469/article/details/77914037
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞