【发布时间】:2012-10-25 19:13:52
【问题描述】:
我对 USACO 培训的 TEXT 动态编程部分中编写的关于经典问题(寻找最大递减子序列)的代码感到困惑。这是Article Link。请帮我搞定!
代码如下:
1 #include <stdio.h>
2 #define MAXN 200000
3 main () {
4 FILE *in, *out;
5 long num[MAXN], bestrun[MAXN];
6 long n, i, j, highestrun = 0;
7 in = fopen ("input.txt", "r");
8 out = fopen ("output.txt", "w");
9 fscanf(in, "%ld", &n);
10 for (i = 0; i < n; i++) fscanf(in, "%ld", &num[i]);
11 bestrun[0] = num[n-1];
12 highestrun = 1;
13 for (i = n-1-1; i >= 0; i--) {
14 if (num[i] < bestrun[0]) {
15 bestrun[0] = num[i];
16 continue;
17 }
18 for (j = highestrun - 1; j >= 0; j--) {
19 if (num[i] > bestrun[j]) {
20 if (j == highestrun - 1 || num[i] < bestrun[j+1]){
21 bestrun[++j] = num[i];
22 if (j == highestrun) highestrun++;
23 break;
24 }
25 }
26 }
27 }
28 printf("best is %d\n", highestrun);
29 exit(0);
30 }
我有 3 个问题:
1) 第 14-17 行到底是做什么的? 例如对于序列 10, 2, 8, 9, 4, 6, 3 ,该代码的结果是 4 但它的子序列是 10, 8, 4, 2 是错误的,因为原始序列中的元素 2 是在 8 和 4 之前,但在结果子序列中是在 8 和 4 之后!
2) 考虑序列 5, 10, 8, 9, 4, 6, 3。根据上面的代码,最大递减子序列的长度是 4,这个子序列是 10,5,4,3。但是在这个与原序列5相反的子序列在10之后。
3) 是否有必要在内部循环中检查num[i] < bestrun[j+1] 条件?我认为它之前满足num[i] > bestrun[j] 条件。
我在等你有用的答案。
感谢您的帮助!
【问题讨论】: