我遇到了这个问题:
给定一个整数,确定仅使用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)时间。我想知道是否有任何其他有效的方法来计算不同集合的数量。
答案 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;
}
memo
开始
(在实践中动态分配)大小不会导致
索引SZ + max_num
的绑定。0
,因为有1种方法
获得empty_sum。k
,还有x种方法可供选择
获取k+2
,k+3
和k+7
。这就是3个循环正在使用的。
(Number_of_ways [{2,3,7} + i] + = number_of_ways [i])给出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++;
}
}