给定多达10,000个整数的序列(0 <整数<100,000),最大减少子序列是多少?请注意,子序列不必是连续的。 递归下降解决方案
解决问题的明显方法是递归下降。人们只需要找到复发和终止条件。请考虑以下解决方案:
1 #include <stdio.h>
2 long n, sequence[10000];
3 main () {
4 FILE *in, *out;
5 int i;
6 in = fopen ("input.txt", "r");
7 out = fopen ("output.txt", "w");
8 fscanf(in, "%ld", &n);
9 for (i = 0; i < n; i++) fscanf(in, "%ld", &sequence[i]);
10 fprintf (out, "%d\n", check (0, 0, 999999));
11 exit (0);
12 }
13 check (start, nmatches, smallest) {
14 int better, i, best=nmatches;
15 for (i = start; i < n; i++) {
16 if (sequence[i] < smallest) {
17 better = check (i+1, nmatches+1, sequence[i]);
18 if (better > best) best = better;
19 }
20 }
21 return best;
22 }
第1-9和第11-12行可以说是样板文件。他们设置了一些标准变量并获取输入。神奇的是第10行和递归例程check
。 check
例程知道它应该从哪里开始搜索较小的整数,到目前为止最长序列的长度,以及到目前为止最小的整数。以额外呼叫为代价,当启动不再在适当范围内时,它会自动终止。 check
例程本身就是简单的。它沿着列表遍历寻找比最小的整数更小的整数。如果找到,check
会递归调用以查找更多
我认为最糟糕的情况是输入完全相反的顺序 喜欢
10 9 8 7 6 5 4 3 2 1
那么这个算法的运行时复杂性是什么,我很难找到它......
答案 0 :(得分:2)
您的问题陈述与最长的子序列问题相匹配。
你没有做任何memoization。在最坏的情况下,您的实现复杂性为Model topic "waiting.gif" "" (Set.fromList [topic])
。因为在每次递归调用时它都会生成O(n^n)
递归调用,依此类推。尝试绘制树并检查叶子的数量。
`
(n-1)
请查看此链接Longest_increasing_subsequence。
同样为了有效实施和更多知识,请检查:Dynamic Programming | Set 3 (Longest Increasing Subsequence)