递归——买书问题

买书问题

描述
小明手里有n元钱全部用来买书,书的价格为10元,20元,50元,100元。
问小明有多少种买书方案?(每种书可购买多本)
输入
一个整数 n,代表总共钱数。(0 <= n <= 1000)
输出
一个整数,代表选择方案种数
样例输入
样例输入1:
20
样例输入2:
15
样例输入3:
0
样例输出
样例输出1:
2
样例输出2:
0
样例输出3:
0
如何分析递归问题 传送门

分析:

这其实是一道完全背包问题,也是作为动态规划的入门题目。
我们这里用递归思想来解决它

  1. n元全部买完书。可以分解为 n-某本书的价格元 可以有几种购买方法,进而求n-某本书 - 某本书有几种购买方法。
  2. base case 直到买完书钱数恰好等于0视为一种成功的情况,统计。如果没有恰好买完,钱超了,或者书的价格数组超出接线,那么视为不成功。
  3. 统计每一层成功与不成功结果里成功的部分,就是答案
import java.util.Scanner;
public class Main {
    static int cost[] = { 10, 20, 50, 100, 0 };

    public static void main(String[] args) {

        Scanner input = new Scanner(System.in);
        int n = input.nextInt();

        System.out.println(process(n, 0));
        // System.out.println(process2(n));
    }

    public static int process(int n, int i) {
        int cnt = 0;
        if (n < 0 || i == 4) {// 用超了和没得选
            return 0;
        }
        if (n == 0) {// 刚好买完
            return 1;
        }
        return  process(n - cost[i], i) + process(n, i + 1);// 买了和没买两种情况
    }

}

完全背包解法

这道题为完全背包问题,可以用一个数组表示对应下标的方案种类数,

再用一个数组储存不同的面值,然后循环相加。
需要注意的是要将a[0]初值设为1,不能设为0;
还有循环从小到大循环,不能从大到小循环,这样就避免了多重复的情况。

import java.util.Scanner;

public class Main {
    static int cost[] = { 10, 20, 50, 100};
    public static void main(String[] args) {
        Scanner input=new Scanner(System.in);
        int arr[]=new int[1001];
        int n=input.nextInt();
        arr[0]=1;
        if(n%10!=0||n==0){
            System.out.println(0);
        }
        else {
            for(int i=0;i<4;++i)
             for(int j=10;j<=n;j+=10)
                { 
                   if(j-cost[i]>=0)
                        arr[j]+=arr[j-cost[i]];
                }
                System.out.println(arr[n]);
          }
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值