暴力的时间复杂度是O(N!)不废话,稍微发现,当出现小于号的时候后面的结构都是一样的,所以使用记忆化方式求,时间复杂度是O(2^n),对于本题的测试数据量50,还是压力非常大的,考虑如下序列,当序列第一次出现小于号的时候,其实就是组合数, 设F[n] = sum(Cn,k*F[n-k]) (1 <= k <= n)
import java.util.*;
import java.math.*;
class Main {
static int MAXN = 51;
static BigInteger[] f = new BigInteger[MAXN];
static void cal(int n) {
BigInteger up, down;
f[0] = BigInteger.valueOf(0x1);
for(int i = 1; i <= n; i ++) {
f[i] = BigInteger.valueOf(0x0);
for(int k = 1; k <= i; k ++) {
down = up = BigInteger.valueOf(0x1);
for(int j = 1; j <= i; j ++) {
up = up.multiply(BigInteger.valueOf(j));
}
for(int j = 1; j <= k; j ++) {
down = down.multiply(BigInteger.valueOf(j));
}
for(int j = 1; j <= i-k; j ++) {
down = down.multiply(BigInteger.valueOf(j));
}
up = up.divide(down);
f[i] = f[i].add(up.multiply(f[i-k]));
}
}
}
public static void main(String [] args) {
for(int i = 1; i < MAXN; i ++) {
cal(i);
}
Scanner scanf = new Scanner(System.in);
int cas, n;
cas = scanf.nextInt();
for(int i = 0; i < cas; i ++) {
n = scanf.nextInt();
System.out.println(f[n]);
}
}
}
hdu_1223 Order Count
最新推荐文章于 2020-09-01 21:55:57 发布
本文详细探讨了如何通过记忆化技术优化递归算法来解决计算组合数的问题,特别是在处理大量测试数据时,这种方法显著提高了效率。通过实例分析,展示了将常规递归算法转换为记忆化递归算法的过程,以及这种改进如何应用于实际问题中。
419

被折叠的 条评论
为什么被折叠?



