【问题标题】:Minimum number of elements required to make two bags of at least k weight?制作两个重量至少为 k 的袋子所需的最少元素数?
【发布时间】:2023-03-20 06:19:01
【问题描述】:

假设给定一个数字 k 和一个具有一定权重的对象数组。现在,您的任务是找出可以放入两个袋子中的最少物品数量,使每个袋子的重量至少为 k。
您只能将物体整体拿走,不允许破坏。此外,如果一个物品放在一个袋子里,它就不能放入另一个袋子里。

这个问题对我来说似乎很简单。当您只需要装满一个袋子时,我也做过类似的问题。我使用的想法是你访问每个对象问自己如果我把它放在袋子里会怎样,如果我不放呢?您递归地执行此操作,直到达到您想要的重量或您没有更多的对象。调用递归函数时取最小值。

但是,我无法理解如何跟踪包 1 中用完的所有对象,因此我不包含在包 2 中。

很少的测试用例

  1. 所需重量 (k) = 4
    对象数 (N) = 1
    [10]
    输出:-1(不可能)
  2. 所需重量 (k) = 2
    对象数 (N) = 3
    [2,2,2]
    输出:2

【问题讨论】:

  • 这里真正考的是对计算机科学和算法的基础知识和理解。如果您不知道答案,那么实现这一点的裸代码转储将不会真正帮助您理解任何东西或学习任何东西。相反,这里的正确答案应该是去学习实现这一点所需的计算机科学和算法的相关领域。不幸的是,stackoverflow.com 不能替代 good C++ and computer science algorithms textbook
  • 我没有要求任何代码转储或复制粘贴解决方案。令我困惑的事情是将对象包含在一个中,而将它们排除在另一个中。给出一个简单的方向将是有帮助和感激的。另外,我认为这并不像最初看起来那么简单。但我知道什么?@SamVarshavchik
  • 您的困惑的确切性质是什么?同样,这只不过是一种算法。如果您不确定“如何跟踪所有对象”或“将对象包含在一个对象中并排除在另一个对象中”,那么您正在寻找解释各种算法的教科书和其他资源。 C++ 库本身提供了许多不同的容器,它们存在的唯一原因是“跟踪它们所包含的对象”。不幸的是,Stackoverflow 不是 C++ 教程网站或教科书的替代品,而是针对特定 问题的。您的具体问题是什么?
  • 我解决了这个问题将很快添加我的解决方案。不知道算法的确切名称是什么。但我认为这是简单的逻辑。@SamVarshavchik

标签: c++ recursion dynamic-programming


【解决方案1】:

这是没有动态编程的程序的伪代码。

 sort(a, a+n); // Sort the array of objects having weight
            int sum = a[n-1], count = -1; //Initialise sum and count
            unordered_set<int>log; // Create an unordered set to store logs (Unordered set will not add repetitive values in the log thus decreasing time complexity)
            log.insert(a[n-1]); // insert last element int log initially
            for(int i = n-2; i >=0; i--) {
                sum += a[i]; //increment the sum
                unordered_set<int>temp; //Create a temporary log that will be mapped to main log at the end.
                temp.insert(a[i]); //insert the sum to temp log
                for (auto it = log.begin(); it != log.end(); ++it) { //loop over all logs seen till now
                    temp.insert(*it + a[i]); // Add current sum to each of them and insert it to temp log thus creating all possible combinations.
                    if((a[i] + *it >= k) && (sum - a[i] - *it >= k)) { //Condition to check if bags have been filled with at least k weight.
                        count = n-i; // update the current count. This will be the ans.
                        break;
                    }
                    if(a[i] >= k && sum - a[i] >= k) {
                        count = n-i;
                        break;
                    }
                }
    
                if(count != -1) { //Condition to check if it's not possible to make such a combination.
                    break;
                }
                log.insert(temp.begin(), temp.end()); // add all temp to main log.
            }
            cout << count << endl; //print ans.

【讨论】:

    【解决方案2】:

    我不知道这是否回答了你的问题,但仍然...... 你可以做一件事:首先创建两个空数组,比如 Bag_1 和 Bag_2。当您逐个递归所有元素时,将该元素从数组中弹出并将其附加到 Bag_1 或 Bag_2 中,以提供最佳解决方案。如果要多次执行该过程,那么如果数组的长度合理,则创建原始数组的副本可能会有所帮助。

    【讨论】:

      【解决方案3】:

      我将重点关注您指出的实际核心问题,即如何跟踪您在一个袋子、另一个袋子中使用过的物品或根本不使用的物品。

      制作一个列表(数组、向量、...任何您喜欢的容器)并记下您使用它的每个对象 - 或不使用它。

      index value meaning
      0 0 not used
      1 0 not used
      2 0 not used
      3 1 used in one bag
      4 2 used in other bag

      根据您的问题,我不清楚输入中是否所有对象都具有相同的权重或不同的权重。如果权重不同,那么您很可能已经有一个容器来跟踪每个对象的重量。修改该容器或使用第二个非常相似的容器将帮助您同时存储“使用过的位置”信息。

      由于
      How do I ask and answer homework questions?

      ,我特意不详细介绍

      【讨论】:

      • 物体的重量也可以相同。例如。如果您有 [7, 8, 19, 7, 8, 7, 10, 20] 作为对象的权重且 k=38,则所需的最小对象数为 7
      • 这是“重量不完全相同”的一个特例,我认为这没有问题。这对你来说是个障碍吗?
      • 我认为这没有任何问题。实际上,我用完全不同的方法解决了这个问题,没有使用任何动态编程,很快就会更新我的解决方案。谢谢。
      • 好,在这里做一个答案,你可以赢得一些声誉。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-16
      • 1970-01-01
      • 2019-08-20
      • 2017-01-24
      • 1970-01-01
      • 2012-09-26
      相关资源
      最近更新 更多