#include <stdio.h>
#define MAX_N 100
#define MAX_K 100
long choose(int n, int k) {
if(n < 0 || n > MAX_N) {
printf("n should be between 0 and %d\n", MAX_N);
return -1;
}
if(k < 0 || k > MAX_K) {
printf("k should be between 0 and %d\n", MAX_K);
return -1;
}
if(n < k) {
printf("n should be greater or equal to k\n");
return -1;
}
if (k == 0 || k == n) {
return 1;
}
static long memorize[MAX_N+1][MAX_K+1];
return memorize[n][k] ?
memorize[n][k] :
(memorize[n][k] = choose(n-1, k) + choose(n-1, k-1));
}
int main(void) {
printf("%ld\n", choose(100, 6));
}
和运行示例:
1192052400
real 0m0.002s
user 0m0.002s
sys 0m0.000s
1条答案
按热度按时间sy5wg1nm1#
你选择一个合适的数据结构来存储你的结果。在这个例子中,我限制了N和K的大小,并使用了一个二维数组(注意:
choose()
是一个快速增长的函数,因此实际上可能会溢出。)。如果结果被缓存,则返回该结果,否则存储新的计算并返回该结果。和运行示例:
我很好奇,所以这里有一个使用动态分配数组版本。@ auttistic在下面指出
mmap()
和open_memstream()
作为替代方案,如果您需要比物理内存更多的空间,mmap()
尤其可以使用文件备份存储。如果memory是一个vla
long (*memorize)[k+1];
,它将允许在choose2()
中使用更自然的memorize[n][k]
语法,这将是一个更漂亮的选择。gcc支持嵌套函数作为扩展,它在这里很有用,所以k_len和memory可以通过外部函数的闭包而不是参数来访问。