简单背包---递归

题目描述
李老师正准备暑假旅行,他有一个容量为L的行李箱和n个物品(n不超过20),每个物品都有自己的体积,物品可以放入行李箱,但行李箱中物品的总体积不能超过行李箱容量,李老师现在想知道他有多少种携带物品的方案(一个物品都不带也算一种方案)

输入数据
第一行为两个正整数n和L,分别代表物品总数和行李箱容量,n<=20,L<=1e9 接下来一行为n个正整数vi,代表第i个物品的体积,vi<=1e8

输出数据
方案数

样例输入
3 10
2 4 5
样例输出
7

解题思路:对每一个物品有两种选择,要或者不要(1/0),从第一个物品一直遍历到最后一个物品,一共有2的n次方种组合方式,对每一种组合判断是否符合携带条件。
在这里插入图片描述
代码:

package homeWork.SeatWork1;

import java.util.Scanner;

/**
 * Created by fangjiejie on 2019/9/19.
 */
public class NumOfItemsToCarry2 {
    public static int count2 = 0;

    public static void cal(int a[], int curIndex, int curWeight, int l) {
        if (curIndex == a.length) {
            if (curWeight <= l) count2++;
            return;
        }
        //每次遍历到一个物品,有两种情况加入或者不加入
        cal(a, curIndex + 1, curWeight, l);
        cal(a, curIndex + 1, curWeight + a[curIndex], l);
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int l = scanner.nextInt();
        int a[] = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = scanner.nextInt();
        }
        count2 = 0;
        cal(a, 0, 0, l);
        System.out.print(count2);
    }
}

这种思路比较简单。还有一种复杂的思路:只装1种物品时有哪些组合,装2种物品时候有哪些组合,装i种物品时有哪些组合。同样用递归实现。直接上代码:

package homeWork.SeatWork1;

import java.util.Scanner;

/**
 * Created by fangjiejie on 2019/9/19.
 */
public class NumOfItemsToCarry {
    /*
    *李老师正准备暑假旅行,他有一个容量为L的行李箱和n个物品(n不超过20),每个物品都有自己的体积,物品可以放入行李箱,但行李箱中物品的总体积不能超过行李箱容量,李老师现在想知道他有多少种携带物品的方案(一个物品都不带也算一种方案)
    * */
    static int count;

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int l = scanner.nextInt();
        int a[] = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = scanner.nextInt();
        }
        count = 0;
        for (int i = 0; i <= n; i++) {
            int result[] = new int[i + 1];
            put(a, 0, i, result, i, l);
        }
        System.out.print(count);
    }

    /*
    * getcount 需要取的组合里的元素个数
    * start 遍历开始索引
    * tempLength 组合的长度
    * tmpArr 每个组合的数据缓存
    * */
    public static void put(int a[], int start, int getcount, int tmpArr[], int tmpLength, int l) {
        if (getcount == 0)//需要取的组合里的元素个数
        {
            int v = 0;
            for (int i = 0; i < tmpLength; i++) {
                v += tmpArr[i];
//               System.out.print(tmpArr[i]+"\t");
            }
            if (v <= l) count++;
//            System.out.println("-----------"+v);
            return;
        }
        if (getcount > (a.length - start) || tmpLength < getcount || getcount < 1) {
            return;
        }
        for (int i = start; i < a.length; i++) {
            tmpArr[tmpLength - getcount] = a[i];
            put(a, i + 1, getcount - 1, tmpArr, tmpLength, l);
        }
        return;
    }


}

发布了184 篇原创文章 · 获赞 60 · 访问量 16万+

猜你喜欢

转载自blog.csdn.net/StubbornAccepted/article/details/101053031