algorithm - 计算给定总和的子集的有效方法

标签 algorithm

给定 N 个数字,我需要计算总和为 S 的子集。

注意:数组中的数字不需要不同。

我当前的代码是:

int countSubsets(vector<int> numbers,int sum)
{
    vector<int> DP(sum+1);
    DP[0]=1;
    int currentSum=0;
    for(int i=0;i<numbers.size();i++)
    {
        currentSum+=numbers[i];
        for (int j=min(sum,currentSum);j>=numbers[i];j--)
            DP[j]+=DP[j - numbers[i]];
    }
    return DP[sum];
}

还有比这更有效的方法吗?

约束是:

1 ≤ N ≤ 14
1 ≤ S ≤ 100000
1 ≤ A[i] ≤ 10000

他们还在一个文件中包含 100 个测试用例。因此,如果他们存在比这个更好的解决方案,请提供帮助

最佳答案

N 很小(2^20 - 大约 100 万 - 2^14 是非常小的值) - 只是遍历所有子集,下面我写了非常快速的方法来做到这一点(bithacking)。将整数视为集合(即按字典顺序枚举子集)

int length = array.Length;
int subsetCount = 0;
for (int i=0; i<(1<<length); ++i)
{
    int currentSet = i;
    int tempIndex = length-1;
    int currentSum = 0;

    while (currentSet > 0) // iterate over bits "from the right side"
    {
       if (currentSet & 1 == 1) // if current bit is "1"
          currentSum += array[tempIndex];

       currentSet >>= 1;
       tempIndex--;        
    }
    subsetCount += (currentSum == targetSum) ? 1 : 0;
}

关于algorithm - 计算给定总和的子集的有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28798047/

相关文章:

algorithm - 不定长数组

c++ - 如何巧妙地将一些元素从 std::set 移动到另一个容器?

algorithm - 棘手的面试难题

python - 时间复杂度 : Cheapst Flights within K stops

java - 不走视觉理想路线的星型算法

arrays - 创建最小成本数组

algorithm - 了解给定代码的时间复杂度

algorithm - 移除最少数量的 Blade

python - 将一组组合合并成一个更大的集合(反向组合)

algorithm - 并行化 A* 以进行昂贵的成本计算