【发布时间】:2014-10-03 02:45:15
【问题描述】:
我比较了两种计算二项式系数 C(n, k) 的算法,如下所示:#1 来自要计算的二项式系数的公式定义,#2 使用动态规划。
#include <stdio.h>
#include <sys/time.h>
#define min(x, y) (x<y?x:y)
#define NMAX 150
double binomial_formula(int n, int k) {
double denominator=1, numerator=1, i;
for (i = 0; i< k; i++)
numerator *= (n-i), denominator *= (i+1);
return numerator/denominator;
}
double binomial_dynamic_pro(int n, int k) {
double c[NMAX][NMAX];
int i,j;
for (i = 0; i <= n; i++) {
for (j = 0; j <= min(i, k); j++) {
if (i == j || j == 0)
c[i][j] = 1;
else
c[i][j] = c[i-1][j-1]+c[i-1][j];
}
}
return c[n][k];
}
int main(void) {
struct timeval s, e;
int n = 50, k = 30;
double re = 0;
printf("now formula calc C(%d, %d)..\n", n, k);
gettimeofday(&s, NULL);
re = binomial_formula(n, k);
gettimeofday(&e, NULL);
printf("%.0f, use time: %ld'us\n", re,
1000000*(e.tv_sec-s.tv_sec)+ (e.tv_usec-s.tv_usec));
printf("now dynamic calc C(%d, %d)..\n", n, k);
gettimeofday(&s, NULL);
re = binomial_dynamic_pro(n, k);
gettimeofday(&e, NULL);
printf("%.0f, use time: %ld'us\n", re,
1000000*(e.tv_sec-s.tv_sec)+ (e.tv_usec-s.tv_usec));
return 0;
}
我用gcc编译,结果是这样的:
now formula calc C(50, 30)..
47129212243960, use time: 2'us
now dynamic calc C(50, 30)..
47129212243960, use time: 102'us
这些结果出乎我的意料。我认为动态规划应该更快,因为它是O(nk),但公式的方法应该是O(k^2),并且它使用乘法,它应该也更慢。
那么为什么动态编程版本会这么慢呢?
【问题讨论】:
-
我认为应该是
O(k)而不是O(k^2)。实际上,我计算了给定 N 和 K 的系数计算所需的步数,formula method需要30步,Dynamic Programming需要1116步。
标签: c algorithm time-complexity