代码之家  ›  专栏  ›  技术社区  ›  GeekyCoder

代码优化子集和

  •  6
  • GeekyCoder  · 技术社区  · 7 年前

    #include <bits/stdc++.h>
    using namespace std;
    
    void traverse(vector<int> vec) {
        for(int a=0; a < vec.size(); a++)
            cout << vec[a] << " ";
        cout << endl;
    }
    
    void possible(vector<int> vec, int sum, vector<int> now) {
        if(sum == 0) {
            traverse(now);
        }
        else if(sum < 0) {
            now.clear();
        }
        else if(sum > 0 && vec.size() > 0) {
            for(int a = 0; a < vec.size(); a++) {
                now.push_back(vec[a]);
                vector<int> vecc(vec.begin() + a + 1, vec.end());
                possible(vecc, sum - vec[a], now);
                now.erase(now.end() - 1);
            }
        }
    }
    
    int main() {
        int n, sum;
        cin >> n >> sum;
    
        vector<int> vec(n), now;
        for(int a = 0; a < n; a++)
            cin >> vec[a];
    
        possible(vec, sum, now);
        return 0;
    }
    

    有没有改进的机会或更快的方法来提高运行时间?

    对此有任何动态问题解决方案吗?

    3 回复  |  直到 7 年前
        1
  •  3
  •   gsamaras    7 年前

    Dynamic Programming | Set 25 (Subset Sum Problem) .

    该问题实际上是NP完全问题(该问题没有已知的多项式时间解)。上面的链接提供了两种解决方案,其中第二种解决方案可以解决 .


    作为技术优化,您可以改变这一点:

    void traverse(vector<int> vec)
    

    void traverse(vector<int>& vec)
    

    为了避免不必要的、可能较大的向量拷贝。如果可以的话,对所有功能都这样做。


    编译代码时启用警告(例如。 -Wall -Wextra 对于GCC),并修复这些警告。然后考虑性能。


    PS: Why should I not #include <bits/stdc++.h>?

        2
  •  2
  •   Mikhail    5 年前

    // To make it simple, returns empty vector if no solution was found
    // and also if the sum is zero
    std::vector<int> find(const std::vector<int>& numbers, int sum)
    {
        std::vector<int> result;
        if (findNumbersMakingSum(numbers, sum, result, 0)) {
            return result;
        } else {
            return std::vector<int>();
        }
    }
    
    bool findNumbersMakingSum(
        const std::vector<int>& numbers,
        int sumLeft,
        std::vector<int>& takenNumbers,
        size_t position)
    {
        if (!sumLeft) {
            // We're done
            return true;
        }
    
        if (position == numbers.size()) {
            return false;
        }
    
        int current = numbers[position];
        if (!current) {
            // Just skip zero elements
            return findNumbersMakingSum(numbers, sumLeft, takenNumbers, position + 1);
        }
    
        // Case 1: take number at current position:
        takenNumbers.push_back(current);
        if (findNumbersMakingSum(numbers, sumLeft - current, takenNumbers, position + 1)) {
            return true;
        }
    
        // Case 2: don't take number at current position
        takenNumbers.pop_back();
        return findNumbersMakingSum(numbers, sumLeft, takenNumbers, position + 1);
    }
    

        3
  •  0
  •   Codor    7 年前

    中提到了动态规划解决方案 this 维基百科关于子集和问题的文章;它通过获得状态空间的两个轴来使用目标值的“组合化”。第一个轴是项目的初始间隔,而第二个轴是期望的目标值。