我正在寻找一种快速的方法来计算n
s.t.对于给定的k
和x
,k
〈= x
.在我的上下文中,对于某个已知的常数n'
,比如说1000,n \leq n'
是1,2,或者3,并且x
是从0 ... n' over k
中随机选择的
我目前的方法是从a_0 = k over k = 1
开始迭代计算二项式系数,下一个系数a_1 = k+1 over k
可以计算为a_1 = a_0 * (k+1) / 1
,依此类推。
uint32_t max_bc(const uint32_t a, const uint32_t n, const uint32_t k) {
uint32_t tmp = 1;
int ctr = 0;
uint32_t c = k, d = 1;
while(tmp <= a && ctr < n) {
c += 1;
tmp = tmp*c/d;
ctr += 1;
d += 1;
}
return ctr + k - 1;
}
int main() {
const uint32_t n = 10, w = 2;
for (uint32_t a = 0; a < 10 /*bc(n, w)*/; a++) {
const uint32_t b = max_bc(a, n, w);
printf("%d %d\n", a, b);
}
}
其输出
0 1
1 2
2 2
3 3
4 3
5 3
6 4
7 4
8 4
9 4
所以我在寻找一个Bittrick或者其他的东西来绕过while
-循环来加速我的应用程序。这是因为while循环最多执行n-k
次。预计算不是一个选项,因为这段代码是一个更大的算法的一部分,它使用了大量的内存。
1条答案
按热度按时间ippsafx71#
如果k真的被限制为1、2或3,则可以根据k使用不同的方法:
C(n, 1) = n
〈= x,所以答案是n
。C(n, 2) = n * (n - 1) / 4
〈= x,可以解方程n * (n - 1) / 4 = x
,正解为n = 1/2 (sqrt(16x + 1) + 1)
,初始问题的答案应为floor( 1/2 (sqrt(16x + 1) + 1) )
。C(n, 3) = n(n-1)(n-2)/6
〈= x。没有好的解决方案,但是组合数的公式很简单,所以可以使用二进制搜索来找到答案。