动态规划(02组合问题)最长递增子序列问题和最长公共子序列问题

文章提供了两个C++代码示例,分别实现了寻找数组中最长递增子序列和两个字符串的最长公共子序列的算法。通过动态规划方法,代码详细地展示了如何计算这两个序列的长度并输出序列本身。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.最长递增子序列代码

#include<iostream>
#include<stdio.h>
#include<windows.h>
using namespace std;

int IncreaseOrder(int a[ ], int n);

//序列顺序不变,子序列满足严格单调递增,可以丢掉中间的一些数
//以该数结尾的最长递增子序列

int main()
{
	int a[]={5,2,8,6,3,6,9,7};
	int len = IncreaseOrder(a, 8);
	cout<<"最长递增子序列的长度是:"<<len<<endl;
	Sleep(80000);
	return 0;
}


int IncreaseOrder(int a[ ], int n)
{
	  int i, j, k, index;
	  int L[10], x[10][10];                 //假设最多10个元素
	  for (i = 0; i < n; i++)                 //1.初始化,最长递增子序列长度为1
	  {
	    L[i] = 1; x[i][0] = a[i];
	  }
	  ///x[0][0]  5 
	  ///x[1][0]  2
	  ///x[2][0]  8............


	  for (i = 1; i < n; i++)                //2.依次计算a[0]~a[i]的最长递增子序列  3个for
	  {
	    int max = 1;                    //初始化递增子序列长度的最大值
		for (j = i - 1; j >= 0; j--)           //对所有的aj < ai
		{
		  if ((a[j] < a[i]) && (max < L[j] + 1)) {
		    max = L[j] + 1; L[i] = max;	
			for (k = 0; k < max-1; k++)    //存储最长递增子序列
			{
				x[i][k] = x[j][k];
			}
			x[i][max-1]= a[i];
		  }
		}
	  }



	  for (index = 0, i = 1; i < n; i++)       //3.求所有递增子序列的最大长度
		if (L[index] < L[i]) index = i;
	  cout<<"最长递增子序列是:";
	  for (i = 0; i < L[index]; i++)         //4.输出最长递增子序列
		cout<<x[index][i]<<"  ";
	  return L[index];                  //返回最长递增子序列的长度
}



2.结果示例
在这里插入图片描述

1.最长公共子序列代码

#include<iostream>
#include<stdio.h>
#include<windows.h>
using namespace std;


int L[10][10],S[10][10];
int CommonOrder(char x[ ], int m, char y[ ], int n, char z[ ]);
int main()
{
	char x[]={'a', 'b', 'c', 'b', 'd', 'b'};
	char y[]={'a','c', 'b', 'b', 'a', 'b', 'd', 'b', 'b'};
	char z[10];
	cout<<"长度为:"<<CommonOrder(x,6,y,9,z)<<endl;
	Sleep(8000);
	return 0;
}
int CommonOrder(char x[ ], int m, char y[ ], int n, char z[ ])
{
	int i, j, k;
	for (j = 0; j <= n; j++)                       //初始化第0行
        L[0][j] = 0;
	for (i = 0; i <= m; i++)                      //初始化第0列
        L[i][0]=0;
	for (i = 1; i <= m; i++)
	{
		for (j = 1; j <= n; j++)
		{
			if (x[i-1] == y[j-1]) 
			{ L[i][j] = L[i-1][j-1] + 1; 
			  S[i][j] = 1; 
			}
			else if (L[i][j-1] >= L[i-1][j]) 
			{ 
				L[i][j] = L[i][j-1];
				S[i][j] = 2;
			}
			else 
			{
				L[i][j] = L[i-1][j];
				S[i][j] = 3; 
			}
		}
	}
	i = m; j = n; k = L[m][n];               //将公共子序列存储到数组z[k]中
    while (i >0 && j >0)
	{
		if (S[i][j] == 1) { z[k] = x[i-1]; k--; i--; j--; }
		else if (S[i][j] == 2) j--;
		     else i--;
	}
	for (k =1; k <=L[m][n]; k++)          //输出最长公共子序列
		cout<<z[k]<<" ";
	cout<<endl;
	return L[m][n];                     //返回公共子序列长度
}

2.结果示例
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值