确定数字的可能组合的数量以获得指定的结果

时间:2014-05-06 08:15:06

标签: algorithm combinations

我遇到了这个问题:

给定一个整数,确定仅使用2,3,7的可能组合的数量,其总和将给出整数。

例如:

4 - 2  {(2,2)}
9 - 3  {(2, 7), (2, 2, 2, 3), (3, 3, 3)}

一种方法是迭代3个循环,然后确定总和是否可达。这是代码:

for( i=0; i<=num/2; i++){
    for( j=0; j<=num/3; j++){
         for( k=0; k<=num/7; k++){
            if(i*2+j*3+k*7 == num) 
                 count++;
}

此处count将具有可能的集合数。但这是非常低效的并且花费O(n3)时间。我想知道是否有任何其他有效的方法来计算不同集合的数量。

2 个答案:

答案 0 :(得分:1)

对于这个问题,dp解决方案应该是线性的。 (Implemented here

#include <stdio.h>
#define SZ 5
int memo[SZ+1+7];


int main(void) {
    int i = 0;
    memset(&memo[0], 0, sizeof memo);
    memo[0] = 1;

    for(i = 0; i <= SZ; ++i) memo[i+2] += memo[i];
    for(i = 0; i <= SZ; ++i) memo[i+3] += memo[i];
    for(i = 0; i <= SZ; ++i) memo[i+7] += memo[i];

    printf("%d\n", memo[SZ]);

    return 0;
}
  1. 我们从一个具有理想无限大小的一维dp数组memo开始 (在实践中动态分配)大小不会导致 索引SZ + max_num的绑定。
  2. 使用1初始化此数组的元素0,因为有1种方法 获得empty_sum。
  3. 如果我们可以通过x方式获得数字k,还有x种方法可供选择 获取k+2k+3k+7。这就是3个循环正在使用的。 (Number_of_ways [{2,3,7} + i] + = number_of_ways [i])
  4. 完成所有循环后, memo [k:0 - SZ]包含数字 我们可以获得的方式
  5. 给出O(k * N)的复杂度,其中k为3(2,3,7)。对于常数k,这是线性的。

答案 1 :(得分:1)

这可以在O(n ^ 2)中解决。

避免上次循环。

for( i=0; i<=num/2; i++){
    for( j=0; j<=num/3; j++){
        k = num - i*2 - j*3;
        if(k%7==0)
                 count++;
    }
}