洛谷 P1049 [NOIP 2001 普及组] 装箱问题

P1049 [NOIP 2001 普及组] 装箱问题

题目描述

有一个箱子容量为 V V V,同时有 n n n 个物品,每个物品有一个体积。

现在从 n n n 个物品中,任取若干个装入箱内(也可以不取),使箱子的剩余空间最小。输出这个最小值。

输入格式

第一行共一个整数 V V V,表示箱子容量。

第二行共一个整数 n n n,表示物品总数。

接下来 n n n 行,每行有一个正整数,表示第 i i i 个物品的体积。

输出格式

  • 共一行一个整数,表示箱子最小剩余空间。

输入输出样例

输入 #1

24
6
8
3
12
7
9
7

输出 #1

0

分析:

  • 箱子的容量是24。
  • 共有6个物品,体积分别是8、3、12、7、9、7。
  • 我们可以通过尝试不同的组合来找到一种使箱子剩余空间最小的选择方式。在这个例子中,可以选择体积为8、7和9的三个物品放入箱子,它们的总体积正好是24,所以箱子的剩余空间是0。

因此,输出结果为0,表示在这种情况下,可以完全填满箱子,没有剩余空间。这个问题可以通过动态规划等方法来解决,以确保找到最优解。

解决方法:

二维方法

#include<bits/stdc++.h>
#define N 31
#define V 20000

using namespace std;
//dp[i][j] 的含义 从 0-i 容量为j 最大能装多少
int dp[N][V];
int x, v, n;

int  main () {
    cin >> v >> n;
    for (int i = 1; i <= n; i++) {
        cin >> x;
        for (int j = 1; j <= v; j++) {
            if (j >= x) 
                dp[i][j] = max(dp[i-1][j], dp[i-1][j-x] + x);
            else
                dp[i][j] = dp[i-1][j];
        }
    }
    cout << v- dp[n][v] << endl;
}


求解过程分析
在这里插入图片描述首先 对于第一行分析,只取或者不取第一个物品
在这里插入图片描述
一维方法,参考了一篇博主的博客,我们在计算二维的时候,
01 背包问题需要注意的问题
就是假设dp[i]的含义是 可以承重i的背包可以放物品的最大体积,然后假设是正序遍历,就是从a[i]到v,当前物品的体积是2,我就更新了dp[2],当处理dp[4]的时候,因为dp[2]已经被更新了,因此可能会再次选取这个体积为2的物品相当于一个物品 放了多次,就变成什么完全背包了,
在这里插入图片描述

#include<bits/stdc++.h>
#define N 31
#define V 20000

using namespace std;
//dp[i][j] 的含义 从 0-i 容量为j 最大能装多少
int dp[V],a[N];
int x, v, n;

int  main () {
    cin >> v >> n;
    for(int i = 1; i <= n; i++){
        cin >> x;
        for(int j = v; j >= a[i]; j--)
           if(j >= x)
                dp[j] = max(dp[j], dp[j-x] + x);            
    }
    cout << v-dp[v] << endl;
    return 0;    
} 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值