NOIP 装箱问题

ゝ一纸荒年。 2024-04-20 07:21 161阅读 0赞

简单说两句

作者:**后端小知识**

CSDN个人主页:后端小知识

?GZH后端小知识

?欢迎关注?点赞?收藏⭐️留言?

题目:[NOIP2001]装箱问题 ,哈哈,我们今天来看一道很古老的题嘛,这是选自NOIP上的一道题,好了,我们一起来看看题意吧:

考虑到直接复制题目,或者截屏的方式不是很方便阅读,我就把直接题目链接放下面!
题目传送门: [NOIP2001]装箱问题

思路:

写过01背包的老板看到这道题时,嘴角微微上扬,说,这还不简单,分分钟AC?

但是,我这里用另一种动态规划的思路

先说说为什么要用动态规划吧:如果用暴力法的话(枚举每个物品装箱还是不装箱),时间复杂度会很高 O(2^n) ?, 我们需要降低时间复杂度。

举个例子:背包容量 20, 5个物品,体积分别为,1,2,2,4,5 ,若我们枚举每个物品放不放的话,时间复杂度是 2^5 ,我们思考下,可以发现我们放两个体积为2的物品和放一个体积为4的物品,对结果是没有影响的。 我们算出这些物品可以放出的体积有: 1,2,3,4,5,6,7,8,9,10,11,12,13,14 这里一共14次(不排除算错的可能哈?),而暴力法的话,有32种情况。

我们采用动态规划的思想呢,时间复杂度为:物品个数*背包体积

我们来看看成功AC的代码吧:

二维数组版

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int n,total;
  4. int v[20010];
  5. int f[35][20010];
  6. int main(){
  7. f[0][0]=1;
  8. cin>>total>>n;
  9. for(int i=1;i<=n;i++) cin>>v[i];
  10. /**
  11. * f[i][j] 表示 0到i 的物品能否填满容量为 j 的背包
  12. */
  13. for(int i=1;i<=n;i++){
  14. for(int j=0;j<=total;j++){
  15. // f[i-1][j] 就表示前面 i-1 件物品能否填满容量为j的背包
  16. // f[i-1][j-v[i]] 表示前面 i-1 件物品能否填满容量为j-v[i]的背包
  17. if(j>=v[i]) f[i][j]=f[i-1][j]||f[i-1][j-v[i]];
  18. else f[i][j]=f[i-1][j];
  19. }
  20. }
  21. int ans=0;
  22. for(int i=total;i>=0;i--){
  23. if(f[n][i]==1){
  24. ans = i;break;
  25. }
  26. }
  27. cout<<total-ans;
  28. return 0;
  29. }

我这里放一张雨巨的图,便于大家理解

image-20221128192238173

我们可以看到每一行的结果实际上只与上一行有关,所以啊,我们可以压缩一下

压缩时有个坑:我们遍历体积的时候,需要从大到小去遍历,这样是为了防止让一个物品多次放入背包(这波操作真的很有意思?)

下面我直接放代码

一维数组版

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int n,total;
  4. int v[20010];
  5. int f[20010];
  6. int main(){
  7. f[0]=1;
  8. cin>>total>>n;
  9. for(int i=1;i<=n;i++) cin>>v[i];
  10. for(int i=1;i<=n;i++){
  11. for(int j=total;j>=v[i];j--){
  12. f[j]=f[j]||f[j-v[i]];
  13. }
  14. }
  15. int ans=0;
  16. for(int i=total;i>=0;i--){
  17. if(f[i]==1){
  18. ans = i;break;
  19. }
  20. }
  21. cout<<total-ans;
  22. return 0;
  23. }

【都看到这了,点点赞点点关注呗,爱你们】??

抽象工厂  引导关注

结语

谢谢你的阅读,由于作者水平有限,难免有不足之处,若读者发现问题,还请批评,在留言区留言或者私信告知,我一定会尽快修改的。若各位大佬有什么好的解法,或者有意义的解法都可以在评论区展示额,万分谢谢。
写作不易,望各位老板点点赞,加个关注!???

?

作者:**后端小知识**

CSDN个人主页:后端小知识

?GZH后端小知识

?欢迎关注?点赞?收藏⭐️留言?

发表评论

表情:
评论列表 (有 0 条评论,161人围观)

还没有评论,来说两句吧...

相关阅读

    相关 【PTA】装箱问题

    题目重述 假设有N项物品,大小分别为s1 、s2 、…、si 、…、sN ,其中si 为满足1≤si ≤100的整数。要把这些物品装入到容量为100的一批箱子(序号1-N

    相关 1014 装箱问题

    题目描述 Description 有一个箱子容量为V(正整数,0<=V<=20000),同时有n个物品(0<n<=30),每个物品有一个体积(正整数)。 要求n个物品中,任

    相关 Java 装箱问题

    问题描述 有一个箱子容量为V(正整数,0<=V<=20000),同时有n个物品(0<n<=30),每个物品有一个体积(正整数)。   要求n个物品中,任取若干个装入箱