DAG最大路径;
AC后我搜了搜,有几个是理解为最大下降子列(我开始也这么想的),但是作为dp的练习题,就化为DAG了,复杂度当然高了,但是没超时。
1 # include <stdio.h>
2
3 int n;
4 int w[1000];
5 int s[1000];
6 int d[1000];
7 int g[1000][1000];
8
9 int dp(int i);
10 void print_list(int i);
11
12 int main()
13 {
14 int i, j, maxl, k;
15
16 n = 1;
17 while (~scanf("%d%d", &w[n], &s[n]))
18 ++n;
19 --n;
20 for (i = 1; i <= n; ++i)
21 for (j = 1; j <= n; ++j)
22 if (w[i]<w[j] && s[i]>s[j])
23 g[i][j] = 1;
24 maxl = 0;
25 for (i = 1; i <= n; ++i)
26 if (maxl < dp(i)) {maxl = d[i]; k = i;}
27
28 printf("%d\n", maxl+1);
29 print_list(k);
30
31 return 0;
32 }
33
34 int dp(int i)
35 {
36 int j;
37 if (d[i] > 0) return d[i];
38 d[i] = 0;
39 for (j = 1; j <= n; ++j)
40 if (g[i][j] && d[i]<dp(j)+1) d[i] = d[j]+1;
41 return d[i];
42 }
43 void print_list(int i)
44 {
45 int j;
46 printf("%d\n", i);
47 for (j = 1; j <= n; ++j)
48 if (g[i][j] && d[i] == d[j]+1)
49 {
50 print_list(j);
51 break;
52 }
53 }
想了想,其实可以省略建图的过程,直接判断就行了:
1 # include <stdio.h>
2
3 int n;
4 int w[1000];
5 int s[1000];
6 int d[1000];
7
8 int dp(int i);
9 void print_list(int i);
10
11 int main()
12 {
13 int i, j, maxl, k;
14
15 n = 1;
16 while (~scanf("%d%d", &w[n], &s[n]))
17 ++n;
18 --n;
19 maxl = 0;
20 for (i = 1; i <= n; ++i)
21 if (maxl < dp(i)) {maxl = d[i]; k = i;}
22
23 printf("%d\n", maxl+1);
24 print_list(k);
25
26 return 0;
27 }
28
29 int dp(int i)
30 {
31 int j;
32 if (d[i] > 0) return d[i];
33 d[i] = 0;
34 for (j = 1; j <= n; ++j)
35 if (w[i]<w[j] && s[i]>s[j] && d[i]<dp(j)+1) d[i] = d[j]+1;
36 return d[i];
37 }
38 void print_list(int i)
39 {
40 int j;
41 printf("%d\n", i);
42 for (j = 1; j <= n; ++j)
43 if (w[i]<w[j] && s[i]>s[j] && d[i] == d[j]+1)
44 {
45 print_list(j);
46 break;
47 }
48 }
这样节省了不小的空间,但时间复杂度不变(O(n*n))。