动态规划___记录路径的最长递增子序列
对比前一篇 背包问题看。此篇特别注意的是 状态转移的范围 (与 状态转移的条件) 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\n", max); 73 printf("index = %d\n", 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("\n"); 94 } 95 return 0; 96 }
http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=1116