洛谷 B3637 最长上升子序列 C语言 记忆化搜索->‘正序‘dp

题目:

https://www.luogu.com.cn/problem/B3637

最长上升子序列

题目描述

这是一个简单的动规板子题。

给出一个由 n(n\\le 5000) 个不超过 10\^6 的正整数组成的序列。请输出这个序列的**最长上升子序列**的长度。

最长上升子序列是指,从原序列中**按顺序**取出一些数字排在一起,这些数字是**逐渐增大**的。

输入格式

第一行,一个整数 n,表示序列长度。

第二行有 n 个整数,表示这个序列。

输出格式

一个整数表示答案。

样例 #1

样例输入 #1

```

6

1 2 4 1 3 4

```

样例输出 #1

```

4

```

提示

分别取出 1234 即可。

思路就是,求出第(1~n)为子序列结尾的最大长度,然后比较一下。用mem数组储存,我画了一个案例图,可以清楚地看出重复部分。

复制代码
#include<iostream>
#include<algorithm> 
using namespace std;
int n;
int nums[5005];
int mem[5005];
int dfs(int k)
{
	if(mem[k])
	return mem[k];
	int sum = 1;
	for(int i = 1 ; i < k ; i++)
	{
		if(nums[i] < nums[k])
		sum = max(sum,dfs(i)+1);
	}
	mem[k] = sum;
	return sum;
}
int main(void)
{
	int ans = -1e10;
	cin >> n;
	for(int i = 1 ; i <= n ; i++)
	cin >> nums[i];
	
	for(int i = 1 ; i <= n ; i++)
	{
		ans = max(ans,dfs(i));
	}
	cout << ans;
	return 0;
 } 

动态规划:'正序'dp

复制代码
#include<iostream>
#include<algorithm> 
using namespace std;
int n;
int nums[5005];
int f[5005];

int main(void)
{
	int ans;
	cin >> n;
	for(int i = 1 ; i <= n ; i++)
	cin >> nums[i];

	for(int i = 1 ; i <= n ; i++)
	{
		f[i] = 1;
		for(int j = 1 ; j < i ; j++)
		{
			if(nums[j] < nums[i])
			f[i] = max(f[i],f[j] + 1);
		}
	}
	sort(f+1,f+1+n);
	ans = f[n];
	cout << ans;
	return 0;
 } 
相关推荐
LjQ20404 分钟前
网络爬虫一课一得
开发语言·数据库·python·网络爬虫
你是狒狒吗11 分钟前
TM中,return new TransactionManagerImpl(raf, fc);为什么返回是new了一个新的实例
java·开发语言·数据库
iceslime17 分钟前
旅行商问题(TSP)的 C++ 动态规划解法教学攻略
数据结构·c++·算法·算法设计与分析
勤奋的知更鸟22 分钟前
Java编程之组合模式
java·开发语言·设计模式·组合模式
虾球xz28 分钟前
CppCon 2015 学习:3D Face Tracking and Reconstruction using Modern C++
开发语言·c++·学习·3d
林鸿群31 分钟前
C#子线程更新主线程UI及委托回调使用示例
开发语言·c#
aichitang20241 小时前
矩阵详解:从基础概念到实际应用
线性代数·算法·矩阵
weixin_461259411 小时前
[C]C语言日志系统宏技巧解析
java·服务器·c语言
OpenCSG2 小时前
电子行业AI赋能软件开发经典案例——某金融软件公司
人工智能·算法·金融·开源