AcWing 895.最长上升子序列Ⅰ + 输出序列
题目链接:http://www.acwing.com/problem/content/897/
浅浅复习
放AC代码
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 const int N = 1010; 5 int n; 6 int a[N], dp[N];//a[i]存储序列,dp[i]存储从第一个数到a[i]的最大公共子序列长度 7 8 int main() 9 { 10 cin >> n; 11 for(int i = 1; i <= n; i ++) 12 cin >> a[i]; 13 14 for(int i = 1; i <= n; i ++) 15 { 16 dp[i] = 1; 17 for(int j = 1; j < i; j ++) 18 { 19 if(a[j] < a[i]) 20 //前一个数的最大公共子序列长度加上自己 21 dp[i] = max(dp[i], dp[j] + 1); 22 } 23 } 24 25 int res = 1; 26 for(int i = 1; i <= n; i ++) 27 res = max(res, dp[i]); 28 29 cout << res <<endl; 30 return 0; 31 }
(倒着)输出最长上升子序列:
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 const int N = 1010; 5 int n; 6 int a[N], dp[N];//a[i]存储序列,dp[i]存储从第一个数到a[i]的最大公共子序列长度 7 int g[N];//g[i]记录dp[i]是由哪个状态转移来的(或者说,记录dp[i]的上一个最大公共子序列的结尾数的位置) 8 9 int main() 10 { 11 cin >> n; 12 for(int i = 1; i <= n; i ++) 13 cin >> a[i]; 14 15 for(int i = 1; i <= n; i ++) 16 { 17 dp[i] = 1; 18 g[i] = 0; 19 for(int j = 1; j < i; j ++) 20 { 21 if(a[j] < a[i]) 22 //前一个数的最长上升子序列长度加上自己 23 //dp[i] = max(dp[i], dp[j] + 1); 24 if(dp[i] < dp[j] + 1) 25 { 26 dp[i] = dp[j] + 1; 27 g[i] = j; 28 } 29 } 30 } 31 32 int k = 1; 33 for(int i = 1; i <= n; i ++) 34 if(dp[k] < dp[i]) 35 k = i;//记录最长上升子序列的最后一位 36 37 cout << dp[k] <<endl; 38 39 for(unsigned int i = 0, len = dp[k]; i < len; i ++) 40 { 41 cout << a[k] <<" "; 42 k = g[k]; 43 } 44 return 0; 45 }