简答:不要使用递归,自下而上使用动态编程。
更长的答案:
基本上,您正在迭代所有可能的解决方案。增加计数的唯一语句是count++,因为我们必须达到一个超过 600 位的数字,这需要一段时间。 (即使不会对每个 count++ 进行函数调用)
所以我们需要以某种方式增加计数,而不是当时只有 1 个。怎么做?
假设我们已经知道 n=2 的答案是 36 种可能性。这是否有助于我们计算 n=3 有多少种可能性?不,不是,因为我们不知道这 36 个数字是什么。其中一个两位数是15,可以扩展为150、151 和159(3 种可能性)。另一个两位数是30,可以扩展为304、305、306、307、308 和309(6 种可能性)。我们显然不能只将 36 乘以某个常数因子来得到 n=3 的解。
但仍然有一个模式。 30 为下一代生成 6 个新数字这一事实意味着 40、50、60 和所有其他以 0 结尾的两位数字也将生成 6 个新数字。 15 产生 3 个新号码,所有其他以 5 结尾的号码也会产生。
如果我们从计算 n=2 开始,而不是记住所有 36 个数字,我们会记住这个数组:[6, 5, 4, 3, 2, 2, 2, 3, 4, 5]。这个数组意味着我们并不确切知道这 36 个数字是什么,但其中 6 个以 0 结尾,其中 5 个以 1 结尾,4 个以 2 结尾,依此类推。
现在我们可以通过做一些加法来计算 n=3 的相同数组。 0 可以从 4、5、6、7、8 或 9 生成。将它们全部加起来意味着对于 n=3,将有 2 + 2 + 2 + 3 + 4 + 5 = 18 个以 0 结尾的数字。 n=3 的整个数组是[18, 16, 14, 12, 15, 16, 15, 18, 20, 22]
不幸的是,我不会说 c,但这是 java 中的解决方案。
import java.util.*;
import java.math.*;
class BigNum {
public static void main (String[] a) {
Scanner in = new Scanner (System.in);
System.out.println (new BigNum().solve(in.nextInt()));
}
BigInteger solve(int n) {
if (n == 0) return BigInteger.ZERO;
BigInteger[] counts = new BigInteger[10];
BigInteger[] next = new BigInteger[10];
BigInteger[] temp;
Arrays.fill (counts, BigInteger.ONE);
counts[0] = BigInteger.ZERO;
for (int i = 1; i < n; i++) {
for (int nextDigit = 0; nextDigit < 10; nextDigit++) {
next[nextDigit] = BigInteger.ZERO;
for (int digit = 0; digit < 10; digit++) {
if (Math.abs (digit - nextDigit) >= 4) {
next[nextDigit] = next[nextDigit].add (counts[digit]);
}
}
}
temp = counts;
counts = next;
next = temp;
}
BigInteger sum = BigInteger.ZERO;
for (BigInteger i : counts) sum = sum.add (i);
return sum;
}
}
它有两个数组:counts 用于当前一代的数组(在上面的示例中 n=2)和next 用于下一代(在示例中 n=3)。当算法完成计算 next 时,它会交换两个数组,这意味着我们将使用这一代的 next 作为下一代的电流。
它有 3 个 for 循环。外循环只计算代数,根本不使用。 nextDigit 计算下一代的数字,而digit 计算当前一代的数字。当它们至少相距 4 时,我们进行加法。
如果你想知道,n=1000 的结果确实很大,我花了 165 毫秒来计算:
58671138329570171371420484902268532315073277852051653969830525802838628724212731137694290047005040297045274423072752812252866695216074181116219893270512906481125049825987756071510466880415373048496191391932743103313044071304405218219902707133109687674960299002863298632965964118240544824530569540542700793488917467060307664191744432111922492168260259079355618958225678548171234101375097873342091776899282686824362584042717489292059166512255400959907373002265039739675037774831081921743873154470907306563401667845616259033848968890244196752759640923743592116170624821165172596009768024780906078208584276112384909371479169927564723938874400811048288种可能性。 P>