最长上升非降子序列的长度动态规划

Posted 晴天下的阳光雨

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最长上升非降子序列的长度动态规划相关的知识,希望对你有一定的参考价值。

第一种dp从后往前:

dp[i]表示以a[i]为起点的最长上升非降子序列的长度

a[8]={10,2,2,4,12,23,34,2}

dp[8]={4,6,5,4,3,2,1,1};

代码实现:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 void logest_increase_sub(const int*a,int ssize)
 4 {
 5     int *dp=new int[ssize]();
 6     int *p=new int[ssize]();
 7     //dp[ssize-1]=1;
 8     for(int i=ssize-1;i>=0;i--)
 9     {
10         int maxn=0,index=0;
11         for(int j=i+1;j<ssize;j++)
12         {
13             if(a[i]<=a[j]&&maxn<dp[j])
14             {
15                 maxn=dp[j];
16                 index=j;
17             }
18         }
19         if(maxn==0)
20         {
21             dp[i]=1;
22             p[i]=-1;
23         }
24         else
25         {
26             dp[i]=maxn+1;
27             p[i]=index;//记录索引
28         }
29     }
30     int max_sum=0,max_index=0;
31     for(int i=0;i<ssize;i++)
32     {
33         cout<<dp[i]<<"  ";
34         if(max_sum<dp[i])
35         {
36             max_sum=dp[i];
37             max_index=i;
38         }
39     }
40     cout<<endl;
41     printf("最长子序列长度: %d\n",max_sum);
42     for(int i=max_index;i!=-1;i=p[i])
43     {
44         cout<<a[i]<<" ";
45     }
46     cout<<endl;
47     delete[]dp;
48     delete[]a;
49 }
50 int main()
51 {
52     int ss[]={1,2,4,1,3};
53     logest_increase_sub(ss,5);
54     return 0;
55 }

 

第二dp从前往后:

dp[i]表示以a[i]为终点的最长上升非降子序列的长度

a[8]={10,2,2,4,12,23,34,2}

dp[8]={1,1,2,3,4,5,6,3};

代码实现:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int main()
 4 {
 5     int a[100],dp[100],p[1000],n,i,j,k,index;
 6     cin>>n;
 7     int maxn=0;
 8     for(i=0;i<n;i++)
 9     cin>>a[i];
10     memset(dp,0,sizeof(dp));
11      memset(p,-1,sizeof(p));
12     dp[0]=1;
13 
14     for(i=0;i<n;i++)
15     {
16         maxn=0;index=-1;
17         for(j=i-1;j>=0;j--)
18         {
19             if(a[j]<=a[i]&&dp[j]>maxn)
20             {
21                 maxn=dp[j];
22                 index=j;
23             }
24         }
25         if(maxn==0)
26         {
27             dp[i]=1;
28             p[i]=-1;
29         }
30         else
31         {
32             dp[i]=maxn+1;
33             p[i]=index;
34         }
35     }
36     for(i=0;i<n;i++)
37     cout<<dp[i]<<" ";
38     cout<<endl;
39     maxn=0;
40     int max_index=-1;
41     for(i=0;i<n;i++)
42    {
43        if(dp[i]>maxn)
44        {
45            maxn=dp[i];max_index=i;
46        }
47    }
48     printf("最长子序列长度: %d\n",maxn);
49     for(i=max_index;i!=-1;i=p[i])
50     cout<<a[i]<<" ";//因为是从前往后的dp所以索引是逆序的
51     cout<<endl;
52     return 0;
53 }

 

以上是关于最长上升非降子序列的长度动态规划的主要内容,如果未能解决你的问题,请参考以下文章

一维偏序最长上升子序列最长非降子序列

最长递增(不减)子序列

动态规划_最长上升子序列plus_最短编辑距离

最长上升子序列(LIS)动态规划

动态规划_最长上升子序列

[luoguP2766] 最长递增子序列问题(最大流)