最长公共递增子序列(C++实现)

原创 2012年03月25日 12:29:14

典型的动态规划题目,可以吧题目转化为最长公共子序列问题,输入一个序列,然后将其排序,储存在另一个数组中。

然后求两个数组的最长公共子序列,求出的最长公共子序列即为输入序列的最长递增子序列。本文还有一个关键部分就

是输出所有的最长递增子序列,代码中使用了一个path[N+1][N+1]数组记录过程,并用回溯的方法输出。

#include <iostream>

#include<string>
using namespace std;
const int N = 100;
int dp[N+1][N+1] ;
int path[N+1][N+1];//记录路径
char str1[N],str2[N];
void  print(int t,int i,int j)//是用回溯的方法输出,输出path[i][j]为0的点
{
    if(t == 0)
        return ;
    if(path[i][j] == 0)
    {
        print(dp[i-1][j-1],i-1,j-1);
        cout<<str2[j-1];
    }
    if(path[i][j] == 1)
        print(dp[i-1][j],i-1,j);
    if(path[i][j] == 2)
        print(dp[i][j-1],i,j-1);
}
int LCSL(int len)
{
    int i , j ;
    for( i = 0 ; i <= len; i++ )//初始化
    {
        dp[i][0] = 0 ;dp[0][i] = 0 ;
    }
    for( i = 1 ; i<= len ; i++)
        for( j = 1 ; j <= len ; j++)
        {
            if(str1[i - 1] == str2[j - 1])
            {
                dp[i][j] = dp[i - 1][ j - 1] + 1;
                path[i][j] = 0;//左上
            }
            else
            {
                if(dp[i - 1][ j ] >= dp[i][j - 1])
                {
                    dp[i][j] = dp[i - 1][ j ];
                    path[i][j] = 1;//上
                }
                else
                {
                    dp[i][j] = dp[i][j - 1];
                    path[i][j] = 2;//右
                }
            }
        }
    for(i=0;i<=len;i++) //输出dp[][]和path[][],括号里为path[][]
    {
        for(j=0;j<=len;j++)
            cout<<dp[i][j]<<"("<<path[i][j]<<")"<<" ";
        cout<<endl;
    }
    for(i=0;i<=len;i++)
    {
        for(j=0;j<=len;j++)
        {
            if(dp[i][j] == dp[len][len] && path[i][j] == 0)
            {
                print(dp[len][len],i,j);
                cout<<endl;
            }
        }
    }
    return dp[len][len];
}
void sort(int num)
{
    for(int i=0;i<num-1;i++)
        for(int j=0;j<num-1-i;j++)
        {
            if(str2[j]>str2[j+1])
            {
                char ch;
                ch = str2[j];
                str2[j] = str2[j+1];
                str2[j+1] = ch;
            }
        }
}
int main()
{
    int num;
    cout<<"输入字符个数:";
    cin>>num;
    cout<<"输入"<<num<<"个字符"<<endl;
    for(int i=0;i<num;i++)
    {
        cin>>str1[i];
        str2[i] = str1[i];
    }
    sort(num);
    LCSL(num);
    system("pause");
      return 0;
}

动态规划——最长递增子序列和最长公共子序列

(1)最长递增子序列 一个序列有n个数:a[1],a[2],…,a[n],求出最长递增子序列的长度。 比如说对于测试数据5,3,4,8,6,7来说: 第一个数字5,d[0] = 1 第一个数字3,...
  • hulamua
  • hulamua
  • 2016年09月14日 16:18
  • 974

最长公共子序列及最长递增子序列NlogN算法及路径记录

原文链接 最长公共子序列路径记录 最长公共子序列转化为最长递增子序列问题,O( n*log(n) )   (转自:http://karsbin.blog.51cto.com/1156716/96...
  • qq_32680617
  • qq_32680617
  • 2016年10月15日 13:40
  • 461

动态规划之,最长公共子序列,最长上升子序列,最长公共递增子序列的长度

动态规划小练习
  • xrwy2000
  • xrwy2000
  • 2017年04月27日 20:05
  • 202

动态规划之最长递增子序列 最长不重复子串 最长公共子序列

【前言】动态规划:与分治法相似,即通过组合子问题来求解原问题,不同的是分治法是将问题划分为互不相交的子问题,递归求解子问题,再将他们组合起来求出原问题的解。 动态规划则应用于子问题重叠的情况,通常用来...
  • sinat_25216047
  • sinat_25216047
  • 2016年05月11日 16:19
  • 1418

动态规划求最长递增子序列

最长递增子序列问题是一个很基本、较常见的小问题,但这个问题的求解方法却并不那么显而易见,需要较深入的思考和较好的算法素养才能得出良好的算法。由于这个问题能运用学过的基本的算法分析和设计的方法与思想,能...
  • qq_21120027
  • qq_21120027
  • 2015年08月18日 18:37
  • 2068

最长递增子序列(输出最长递增序列 及其长度)

最长递增子序列的解法有很多种,常用的有最长公共子序列法、动态规划、记录所有递增序列长度最大值的方法。   最长公共子序列法:如例子中的数组A{5,6, 7, 1, 2, 8},则我们排序该...
  • bigbigtree911
  • bigbigtree911
  • 2014年09月22日 10:38
  • 1841

最长递增子序列 LIS 时间复杂度O(nlogn)的Java实现

求最长递增(递减)子序列 LIS时间复杂度O(nlogn)的Java实现...
  • iNiegang
  • iNiegang
  • 2015年08月15日 13:20
  • 2198

nyist oj 17 单调递增最长子序列 (动态规划经典题)

单调递增最长子序列 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描述求一个字符串的最长递增子序列的长度 如:dabdbf最长递增子序列就是abd...
  • u014253173
  • u014253173
  • 2014年08月15日 11:37
  • 4320

NKOI 1941 最长递增子序列

【线性规划与网络流24题 6】最长递增子序列 Time Limit:10000MS  Memory Limit:65536K Total Submit:19 Accepted:2  Case T...
  • getsum
  • getsum
  • 2016年08月06日 20:56
  • 408

最长递增子序列

一、题目描述 描述: N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学不交换位置就能排成合唱队形。  合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1, 2,...
  • u013074465
  • u013074465
  • 2015年05月02日 20:40
  • 4040
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:最长公共递增子序列(C++实现)
举报原因:
原因补充:

(最多只允许输入30个字)