最长递增子序列和-题解

一、题目链接

https://www.nowcoder.com/practice/dcb97b18715141599b64dbdb8cdea3bd?tpId=40&rp=1&ru=%2Fta%2Fkaoyan&qru=%2Fta%2Fkaoyan%2Fquestion-ranking&tab=answerKey

二、题目分析

算法思路:动态规划

算法分析:

用dp[i]记录遍历到a[i]时当前最长递增子序列和,采用双层循环,第一层遍历数组a,第二层更新dp[i](如果a[j]<a[i],判断是否要更新dp[i],也即是否把a[i]加入到以a[j]结尾的递增子序列中,dp[i]=max(dp[i],dp[j]+a[i])

代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,a[1001],dp[1001];
 4 int main(){
 5     while(cin>>n){
 6     int ans=0;
 7     for(int i=0;i<n;i++){
 8         cin>>a[i];dp[i]=a[i];
 9     }
10     for(int i=0;i<n;i++){
11         for(int j=i-1;j>=0;j--){
12             if(a[j]<a[i]) dp[i]=max(dp[i],dp[j]+a[i]);
13         }
14         ans=max(ans,dp[i]);
15     }
16     cout<<ans<<endl;    
17     }
18 }

若问最长上升子序列的长度,代码如下:

注:只需修改dp的值,dp[i]值从【最长递增子序列】和变成【最长递增子序列】长度

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,a[1001],dp[1001];
 4 int main(){
 5     while(cin>>n){
 6     int ans=0;
 7     for(int i=0;i<n;i++){
 8         cin>>a[i];dp[i]=1;//修改这 
 9     }
10     for(int i=0;i<n;i++){
11         for(int j=i-1;j>=0;j--){
12             if(a[j]<a[i]) dp[i]=max(dp[i],dp[j]+1);//修改这 
13         }
14         ans=max(ans,dp[i]);
15     }
16     cout<<ans<<endl;    
17     }
18 }

问最长上升子序列的长度,并且要输出其中一个最长上升子序列,代码如下:

注:

 1 #include<bits/stdc++.h>
 2 #define N 100005
 3 using namespace std;
 4 int num[N],a[N],pre[N],pos[N];
 5 void print(int x){
 6     if(x==0) return;
 7     print(pre[x]);
 8     cout<<num[x]<<" ";
 9 }
10 int main(){
11     int n;
12     while(cin>>n){
13         memset(a, 0x3f, sizeof(a));
14         int len = 0;
15         for(int i=1; i<=n; ++i){
16             cin>>num[i];
17             int ll = lower_bound(a, a+len, num[i]) - a;
18             if(ll+1 > len) len = ll+1;
19             a[ll] = num[i];//第ll个位置新插入的数字num[i] 
20             pos[ll] = i;//第ll个位置插入的是第i个数字 
21             if(ll-1>=0) pre[i] = pos[ll-1];//当前插入的第i个数字的在递增序列中的前一个数字是第几个! 
22         }
23         print(pre[pos[len-1]]);
24         cout<<(num[pos[len-1]])<<endl;
25         cout<<len<<endl;
26     }
27     return 0;
28 }
posted @ 2021-03-15 17:21  saaas  阅读(71)  评论(0编辑  收藏  举报