蓝桥杯——说好的进阶之装箱问题

本文探讨了解决背包问题的多种算法实现,包括递归解法、01背包动态规划和改进动态规划方法,详细解释了每种方法的原理和步骤,并通过实例展示了如何在给定条件下求解剩余最小容量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有一个箱子容量为v(正整数,0≤v≤20000),同时有n个物品(0<n≤30),每个物品有一个体积(正整数)。 


要求从n个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。 输入: 


箱子的容量v   物品数n 


 接下来n行,分别表示这n个物品的体积。

输出最多可以装多大容量

输入:

24    
6    

8     

12 

7

输出:24

/*
	 * 输入:
	24
	6
	8
	3
	12
	7
	9
	7
	输出:24
	同理求剩余最小容量,相减即可
	*/
	static int[] tj;
	static int V;
	static int[][] l;

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner scanner = new Scanner(System.in);
		V = Integer.parseInt(scanner.nextLine());
		int n = Integer.parseInt(scanner.nextLine());
		min_v=V;
		tj = new int[n];
		l = new int[n + 1][V + 1];
		for (int i = 0; i < n; i++) {
			tj[i] = Integer.parseInt(scanner.nextLine());
		}

		vis = new boolean[n];
		
		//法一.递归解法,效率不高
		all(0);
		System.out.println(min_v);
		
		//法二:0 1 背包 动态规划
		cal();
		
		//法三:改进 动态规划
		k();
	}
	
	static void k()
	{
		int b[] =new int[V+1];
		for(int i=0;i<tj.length;i++)
		{
			for(int j=V;j>= tj[i];j--)
			{
				b[j] = Math.max(b[j], b[j-tj[i]]+tj[i]);
			}
		}
		
		for(int i:b)
		{
			System.out.print(i+" ");
		}
		System.out.println();
		System.out.println(b[V]);
	}

	static boolean[] vis;
	static int min_v;
	static void all(int i)
	{
		if(i==tj.length)
		{
			//find
			int tmp=0;
			for(int j=0;j<vis.length;j++)
			{
				if(vis[j])
				{
					tmp+=tj[j];
				}
			}
			
			if(tmp<=V && min_v>V-tmp)
			{
				min_v=V-tmp; 
			}
			return;
		}
		vis[i] =true;
		all(i+1);
		vis[i]=false;
		all(i+1);
	}
	
	// 0 1 背包
		static void cal() {
			for (int j = 1; j < l[0].length; j++) {
				for (int i = 1; i < l.length; i++) {
					if (tj[i - 1] > j) {
						l[i][j] = l[i - 1][j];
					} else {
						if (l[i - 1][j - tj[i - 1]] + tj[i - 1] > l[i - 1][j]) {
							l[i][j] = l[i - 1][j - tj[i - 1]] + tj[i - 1];
						} else {
							l[i][j] = l[i - 1][j];
						}
					}
				}
			}

			for (int[] i : l) {
				for (int j : i) {
					System.out.print(j + " ");
				}
				System.out.println();
			}

			get(V, tj.length);
		}

		static void get(int v, int i) {
			if (i == 0 || v == 0)
				return;

			if (l[i][v] > l[i - 1][v]) {
				get(v - tj[i - 1], i - 1);
				System.out.print(i + " ");
			} else {
				get(v, i - 1);
			}
		}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值