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 }

 

posted @ 2022-10-21 21:01  爱吃虾滑  阅读(30)  评论(0编辑  收藏  举报