牛牛的背包问题 —— 01背包问题

1 牛牛的背包问题

牛牛的背包问题 —— 牛客网
问题描述:
牛牛准备参加学校组织的春游, 出发前牛牛准备往背包里装入一些零食, 牛牛的背包容量为w。

牛牛家里一共有n袋零食, 第i袋零食体积为v[i]。

牛牛想知道在总体积不超过背包容量的情况下,他一共有多少种零食放法(总体积为0也算一种放法)。

输入描述:
输入包括两行
第一行为两个正整数n和w(1 <= n <= 30, 1 <= w <= 2 * 10^9),表示零食的数量和背包的容量。
第二行n个正整数v[i](0 <= v[i] <= 10^9),表示每袋零食的体积。

2 编程实现

package com.cow;

import java.util.Scanner;

/*
21 1165911996
842104736 130059605 359419358 682646280 378385685 622124412 740110626 814007758 557557315 40153082 542984016 274340808 991565332 765434204 225621097 350652062 714078666 381520025 613885618 64141537 783016950
*/
public class Cow {
	private static int methodNum = 0;
	public static void main(String[] args) {
		int n;
		Long w;//注意:此题测试数据的N个物品,其体积和会超过int范围。
		Scanner input = new Scanner(System.in);
		n = input.nextInt();
		w = input.nextLong();

		input.nextLine();//读入当前行的最后一个字符,即换行符。然后将指针指向下一行
		String line = input.nextLine();//此时指针指向行首,读取当前行
		input.close();
		
		String[] splitLine = line.split(" ");
		
		int[] v = new int[n+1];
		Long total = 0L;
		for (int i = 0; i < splitLine.length; i++) {
			v[i + 1] = Integer.parseInt(splitLine[i]);
			total += v[i + 1];
		}
		
		if(total <= w) methodNum = (int) Math.pow(2, n);
		else {
			calMethodNum(n,w,v,0L,1); //当前包里的重量为0,当前检查零食为第1包
		}
		System.out.println(methodNum);
	}
	
	private static void calMethodNum(int n, Long w, int[] v,Long sum,int loc) {
		if(sum > w) {
			return;
		}
		
		if(sum <= w) {
			methodNum ++;
		}
		
		for(int i=loc;i<=n;i++) {//每一个i对应的包里的剩余容积,都是相同的。
			if(w - sum > v[i]) {//如果包里的剩余容积 大于 第i个物品的体积,就将其装入包中。
				calMethodNum(n, w, v, sum + v[i], i+1);
			}
			//上面的if结束,再去查看第i+1个物品,能否放入现在的包里。出来if后,现在的包里已经没有物品i了。
		}
	}
}

你可能感兴趣的:(数据结构)