动态规划——最长上升子序列模型
创始人
2024-03-16 03:54:16
0

最长上升子序列模型:

给定一个长度为 N 的数列,求数值严格单调递增的子序列的长度最长是多少。

输入格式:

第一行包含整数 N。

第二行包含 N 个整数,表示完整序列。

输出格式:

输出一个整数,表示最大长度。

例如:3 1 2 1 8 5 6这个序列的最长递增子序列长度为4(1 2 5 6)。

思路:

f[i]表示以i为结尾的所有上升子序列中最长的那个序列的长度。状态计算:f[i]=f[j]+1,f[j]为i前面的子序列中可以连接到i前面的最长的一个序列(也就是j

代码如下:
 

#includeusing namespace std;
const int N = 1010;
int f[N], a[N];
int n, res = 1;int main() {cin >> n;for (int i = 0; i < n; i++) {cin >> a[i];f[i] = 1;for (int j = 0; j < i; j++)if (a[j] < a[i]) {f[i] = max(f[i], f[j] + 1);res = max(res, f[i]);}}cout << res;return 0;
}

例题:

1.怪盗基德:

假设城市中一共有N幢建筑排成一条线,每幢建筑的高度各不相同。

初始时,怪盗基德可以在任何一幢建筑的顶端。

他可以选择一个方向逃跑,但是不能中途改变方向。

因为滑翔翼动力装置受损,他只能往下滑行(只能从较高的建筑滑翔到较低的建筑)。

他希望尽可能多地经过不同建筑的顶部。

请问,他最多可以经过多少幢不同建筑的顶部。

输入格式:

输入数据第一行是一个整数K,代表有K组测试数据。

每组测试数据包含两行:第一行是一个整数N,代表有N幢建筑。第二行包含N个不同的整数,每一个对应一幢建筑的高度h,按照建筑的排列顺序给出。

输出格式:

对于每一组测试数据,输出一行,包含一个整数,代表怪盗基德最多可以经过的建筑数量。

思路:

我们求出以每个点为结尾的最长上升子序列的长度,就是求出了以每个点为起点向左往下飞的最多建筑数量;

我们求出以每个点为结尾的最长下降子序列的长度,就是求出了以每个点为终点的往右飞的最多建筑数量。

所以我们求出两者取最大值即可。

代码如下:
 

#include
using namespace std;
const int N = 110;
int a[N], f_up[N], f_down[N];
int K, n;int main() {cin >> K;while (K--) {cin >> n;int max_u = 1, max_d = 1;for (int i = 0; i < n; i++) {cin >> a[i];f_up[i] = f_down[i] = 1;for (int j = 0; j < i; j++) {if (a[j] < a[i]) { f_up[i] = max(f_up[i], f_up[j] + 1); max_u = max(max_u, f_up[i]); }else if (a[j] > a[i]) { f_down[i] = max(f_down[i], f_down[j] + 1); max_d = max(max_d, f_down[i]); }}}cout << max(max_u, max_d) << endl;}return 0;
}

2.登山:

山上一共有N个景点,每个景点有对应的编号。

队员决定按照顺序来浏览这些景点,即每次所浏览景点的编号都要大于前一个浏览景点的编号。

同时队员们还有另一个登山习惯,就是不连续浏览海拔相同的两个景点,并且一旦开始下山,就不再向上走了。

问最多能浏览多少个景点。

思路:

要求的是先上升再下降的最长子序列。

从前往后求一遍上升子序列;

从后往前求一遍上升子序列(相当于从前往后下降)。

然后找出哪个点的上升和下降子序列之和最大,答案就是最大值减一。

代码如下:

#include
using namespace std;const int N = 1010;
int a[N], f_up[N], f_down[N];
int n, res = 1;int main() {cin >> n;for (int i = 0; i < n; i++) {cin >> a[i];f_up[i] = 1;for (int j = 0; j < i; j++)if (a[j] < a[i])f_up[i] = max(f_up[i], f_up[j] + 1);}for (int i = n - 1; i >= 0; i--) {f_down[i] = 1;for (int j = n - 1; j > i; j--)if (a[j] < a[i])f_down[i] = max(f_down[i], f_down[j] + 1);res = max(res, f_down[i] + f_up[i]);}cout << res - 1;return 0;
}

相关内容

热门资讯

汽车油箱结构是什么(汽车油箱结... 本篇文章极速百科给大家谈谈汽车油箱结构是什么,以及汽车油箱结构原理图解对应的知识点,希望对各位有所帮...
美国2年期国债收益率上涨15个... 原标题:美国2年期国债收益率上涨15个基点 美国2年期国债收益率上涨15个基...
嵌入式 ADC使用手册完整版 ... 嵌入式 ADC使用手册完整版 (188977万字)💜&#...
重大消息战皇大厅开挂是真的吗... 您好:战皇大厅这款游戏可以开挂,确实是有挂的,需要了解加客服微信【8435338】很多玩家在这款游戏...
盘点十款牵手跑胡子为什么一直... 您好:牵手跑胡子这款游戏可以开挂,确实是有挂的,需要了解加客服微信【8435338】很多玩家在这款游...
senator香烟多少一盒(s... 今天给各位分享senator香烟多少一盒的知识,其中也会对sevebstars香烟进行解释,如果能碰...
终于懂了新荣耀斗牛真的有挂吗... 您好:新荣耀斗牛这款游戏可以开挂,确实是有挂的,需要了解加客服微信8435338】很多玩家在这款游戏...
盘点十款明星麻将到底有没有挂... 您好:明星麻将这款游戏可以开挂,确实是有挂的,需要了解加客服微信【5848499】很多玩家在这款游戏...
总结文章“新道游棋牌有透视挂吗... 您好:新道游棋牌这款游戏可以开挂,确实是有挂的,需要了解加客服微信【7682267】很多玩家在这款游...
终于懂了手机麻将到底有没有挂... 您好:手机麻将这款游戏可以开挂,确实是有挂的,需要了解加客服微信【8435338】很多玩家在这款游戏...