递归5:【SSL】1169 装箱问题——2021-03-06更

7 篇文章 0 订阅
本文介绍了一种利用递归解决装箱问题的方法,通过剪枝减少计算量,重点在于如何在n=30物品和V=20000箱子的限制下,找到使剩余空间最少的物品组合。代码实现中运用了动态规划思想,避免了直接枚举所有可能的放置方式。
摘要由CSDN通过智能技术生成

递归5:【SSL】1169 装箱问题

题目:

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

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

输入样例
24
6
8 
3
12
7
9
7

输出样例
0

思路:

这道题目的话其实思路好想,但是因为数据太大所以要注意优化。
认真思考,不难发现一个箱子只有2中方法,放或不放。举个例子,用1表示放,0表示不放,假设有3个箱子,那么就有8种方法:
111
110
101
100
011
010
001
000
所以可以得出结论:n个箱子有2的n次方种放法。
但是n最大是30,2^30是十亿多,如果挨个试必然会超时,那么就要优化一下。如果把递归当成一棵树,那么只要找到条件判断,就可以剪掉一部分枝叶,这样就可以少很多运行次数,因为题目中说明了要让箱子里尽可能地使空间变少,所以每次递归时判断一下,只要我剩下的所有体积加上箱子里已经占用的空间还小于或等于我目前求出来的最大值,那么这个递归就可以结束了,返回到上一层。

代码:

#include<bits/stdc++.h>
using namespace std;
int n,v,a[50],h,b[50];

void dg(int p,int s,int sy)
{
	if(p>n)
	{
		h=max(h,s);
		return ;
	}
	if(s+b[n]-b[p-1]<=h)
		return ;
	if(sy>=a[p])
		dg(p+1,s+a[p],sy-a[p]);
	dg(p+1,s,sy);
}
int main()
{
	cin>>v>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		b[i]=b[i-1]+a[i];
	}
	dg(1,0,v);
	cout<<v-h;
	return 0;
} 
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值