装箱问题(DP)

题目描述

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

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

输入

第一行为一个整数,表示箱子容量;

第二行为一个整数,表示有n个物品;

接下来n行,每行一个整数表示这n个物品的各自体积。

输出

一个整数,表示箱子剩余空间。

样例输入

24

 6

 8

 3

 12

 7

 9

 7

样例输出

0

 

  1. 这个题目运用到了dp(动态规划)。
  2. 我们首先需要开辟一个大小比v大一点的数组dp,这个数组用来模拟放置物品。
  3. 我们每一次得到要放进去的容量,从dp数组最后一个下标就也是v开始模拟,也就是j=v,是v是因为,我们最多放置v那么大的容量。
  4. 然后往前推算,这个box[i]到底放不放。推算结束条件是什么?就是我们前一次放的那个下标不能是小于0的,也就是j>=box[i]
  5. 前一次记录结果是存在dp[j-box[i]]中的(如果我们要拿这个box[i],我们就得看当容量为dp[j-box[i]]时取得的最优解),如果这个值加上box[i]的值,那么我就就拿这个box[i],否则就保持原来的值(就是一个拿和不拿问题)。
  6. 在我们重复5这个动作的时候,我们最终能保证dp[v]就是最大能拿的容量,那么v-dp[v]就是最小剩余的容量。

代码如下:

#include<stdio.h>
int dp[20005];//表示容积为v时可放置物品的容量
int max(int a,int b)
{
	if(a>=b) return a;
	return b;
}
int main()
{
	int v,n,i,j;
	scanf("%d%d",&v,&n);
	int box[40] = {0};
	for(i = 0;i<n;i++)
	{
		scanf("%d",&box[i]);
	}
	
	for(i = 0;i < n; i++)
	{
		//每一个试着判断放进去
		for(j = v ;j >= box[i]; j--)
		{
			dp[j] = max(dp[j],dp[j-box[i]] + box[i]);//每次贪心放不放下这个box[i],每次都要保证时最优解,也就是最大能拿的。
		//每次都从v往前面贪心,j-box[i]是在查看如果我们要放进去,那么剩下的容量的最优解
		//如果放进去比本来大,就放进去,否则不放
		
		}
	}
	printf("%d",v-dp[v]);//dp[v]这个元素会记下最终贪心的结果
	
	return 0;
}

 

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值