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


    第一种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
    ",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
    ",maxn);
    49     for(i=max_index;i!=-1;i=p[i])
    50     cout<<a[i]<<" ";//因为是从前往后的dp所以索引是逆序的
    51     cout<<endl;
    52     return 0;
    53 }
  • 相关阅读:
    大数据面试题题库
    IDEA下通过Git实现代码管理
    使用QJM实现HDFS的HA配置
    1、HDFS分布式文件系统
    分析system_call中断处理过程
    由一段代码解析系统调用的原理
    从linux内核代码分析操作系统启动过程
    一个简单的时间片轮转多道程序内核
    从一段代码的汇编看计算机的工作原理
    九度OJ1468
  • 原文地址:https://www.cnblogs.com/WHLdbk/p/6538726.html
Copyright © 2020-2023  润新知