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

目录

思想

代码实现


思想:

首先遍历数组:依次遍历  遍历第一个比较他前面的有没有小于它的数字, 如果没有dp[i]赋值为1

如果有查找大于a数组数字,并且对应的dp数组当中为最大数字,然后 找到他应得下表 j  此时count = dp[i];然后count++;就是count+1;然后dp[i]=count;

举例:

第一次执行结束:

 

 此时dp[i] 的位置放1;

第二次执行:

 

到这这里 我们发现a[i]的左边 6<7; 所以把count=dp[j]; 然后 count++; 然后  dp[i]=count;

 

这里比较好的就是控制这个j下标 正好遍历了a[i]前面的数字;同时可以进行比较;

找到刚刚小于a[i]数字a[j];  对应的count=dp[j]; count++ ;  dp[i]=count;

最终执行结果 dp数组存放的就是递增的次数: 

最后效果,然后再数组dp中查找最大值, 就是对应的最大递增子序列的长度。

 

代码实现:

#define _CRT_SECURE_NO_WARNINGS 1


#include<stdio.h>
#include<stdlib.h>


void Find_IncreaseChildSequence(int* a, int N, int* dp)
{

	for (int i = 0; i < N; i++)
	{
		
		int count = 0;
		for (int j = i-1; j >= 0; j--)
		{
			//查找比a[i]小的值
			if (a[j] < a[i])
			{
				//比较
				if (count <= dp[j])
				{
					//把dp[j]赋值给 count;
					count = dp[j];
					count++;
				}
				
				//放在dp中
				dp[i] = count;
				
			}
			
		}

		if (dp[i] == 0)
		{
			dp[i] = 1;
		}


		
	}



}
int main()
{
	int N = 0;
	int tmp = 0;
	printf("请输入需要查找子序列数组元素的个数:>");
	scanf("%d", &N);

	int* a = (int*)malloc(sizeof(int) * N);
	printf("请输入数组元素的值(元素中间以空格隔开):>");
	for (int i = 0; i <	N; i++)
	{
		scanf("%d", &a[i]);
	}

	//建立数组dp 里面存放每个数子序列 递增的长度
	int* dp = (int*)malloc(sizeof(int) * N);
	for (int i = 0; i < N; i++)
	{
		dp[i] = 0;
	}

	//调用函数实现查找自增子序列功能  使得所有子序列递增情况的长度 放在dp数组当中
	Find_IncreaseChildSequence(a, N, dp);

	//在dp数组中查找最大值对应的就是最大递增子序列的长度
	for (int i = 1; i < N; i++)
	{
		if (dp[i] > dp[i - 1])
		{
			if (tmp < dp[i])
			{
				tmp = dp[i];
			}
			
		}
		else
		{
			if (tmp < dp[i - 1])
			{
				tmp = dp[i - 1];

			}
		}
	}

	printf("数组最长递增子序列的长度为:> %d\n", tmp);

	free(dp);
	dp = NULL;


	free(a);
	a = NULL;
	return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值