动态规划___记录路径的最长递增子序列

对比前一篇 背包问题看。此篇特别注意的是 状态转移的范围 (与 状态转移的条件) line31 & 33

以及 每一个状态的初值处理,并利用这个初值 处理递归最后一层的情况 line30

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <iostream>
 5 #include <stack>
 6 
 7 using namespace std;
 8 
 9 #define MAX 110
10 #define INF -1
11 
12 int height[MAX];
13 int map[MAX];
14 int N;
15 stack<int> s;    
16 
17 int max(int a, int b)
18 {
19     return a>b?a:b;
20 }
21 
22 int dp(int cur)
23 {
24     if(map[cur] != INF)
25     {
26         return map[cur];
27     }
28     else
29     {
30         map[cur] = 1;//此时不是0了,因为递增序列只有1个值的时候 长度为1,而且长度为0
31         for(int i = 0 ; i < cur; i++)//转移的范围!!!  注意是 cur 不是N !
32         {
33             if(height[cur] > height[i])//转移的条件
34             {                
35                 map[cur] = max(map[cur], dp(i) + 1);
36             }
37         }
38         return map[cur];
39     }
40 }
41 
42 int main()
43 {
44     //freopen("1.txt", "r", stdin);
45     int i;
46 
47     while(scanf("%d", &N) == 1  && N)
48     {
49        // && N 就不用在这里判断 N是否为0了  

50 // 即 if(N==0)   break;
51 52 memset(map, INF, sizeof(map));//永远不要忘记初始化啊! 53 while( !s.empty() ) 54 s.pop(); 55 for(i = 0; i < N; i++) 56 { 57 scanf("%d", &height[i]); 58 } 59 60 int max = 0; 61 int temp = dp(0);//初始化为第一个 62 int index = 0; 63 for(i = 1; i <= N-1; i++)//循环从第二个开始 64 { 65 temp = dp(i); 66 if(temp > max) 67 { 68 max = temp; 69 index = i; 70 } 71 } 72 /* printf("max = %d ", max); 73 printf("index = %d ", index); 74 for(i = 0 ; i < N; i++) 75 printf("%d ",map[i]); 76 puts("");*/ 77 s.push(index); 78 for(i = index - 1; i >= 0; i--) 79 { 80 if(map[i] == max-1 && height[i] < height[index]) 81 { 82 s.push(i); 83 max--; 84 index = i; 85 } 86 } 87 printf("The number is %d:", s.size()); 88 while( !s.empty() ) 89 { 90 printf(" %d", s.top() + 1); //注意题目要求即可 91 s.pop(); 92 } 93 printf(" "); 94 } 95 return 0; 96 }

http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=1116

原文地址:https://www.cnblogs.com/wwjyt/p/3163939.html