繁体   English   中英

从小于或等于某个 N 的数字列表中最小化或找到理想的子集和

[英]Minimize or find a n ideal subset-sums from a list of numbers which are less than or equal to some N

给定一个数字列表, lst = [1, 1, 2, 4, 3, 2, 1, 1, 1, 2, 1, 4, 3, 1]我将如何找到小于或等于4?

这里有很多可能性。 目标是最小化可能列表的数量。 该程序需要创建如下所示的子集列表: {4}, {4}, {3, 1}, ... , {1, 1}

请注意最后一个列表子集如何不等于 4,而是小于 4。 这个问题很困难,原因如下:

  • 程序必须能够找到小于或等于总和的subset-sums总和
  • 该方案将需要首先清除值超出原来的列表为集列表首先看最大值

这是我的尝试。 一般的想法是对列表进行排序,从左到右,每次迭代都贪婪地选择最大的子集。 时间复杂度是O(n)

#include <iostream>
#include <vector>
#include <algorithm>

int main()
{
    std::vector<int> lst{1, 1, 2, 4, 3, 2, 1, 1, 1, 2, 1, 4, 3, 1};
    std::sort(lst.begin(),lst.end()); //sort the list
    int target = 4;

    int left = 0;
    int right = lst.size()-1;

    std::vector<std::vector<int>> solutions;
    while (left<right ){
        if(lst[left] > target)   // break if no solutions
            break;

        if(lst[right] > target) // ignore larger right values
            right--;


        if(lst[right]<=target){   // while the total sum is less than target, keep adding the elements
            std::vector<int> subset;
            subset.push_back(lst[right]);
            int sum = lst[right];
            while(left<right && lst[left]+sum<=target){
                sum+=lst[left];
                subset.push_back({lst[left]});
                left++;
            }
            solutions.push_back(subset);
            right--;
        }

    }

    for(auto& ss : solutions){
        std::cout<<'{';
        for(auto n:ss){
            std::cout<<n<<',';
        }
        std::cout<<"\b}";
        std::cout<<std::endl;
    }

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM