You are on page 1of 8

《算法设计与分析》实验报告

计算机与信息学院
算法设计与分析实验报告

专 业 班 级
智能科学与技术 20-1

学生姓名及学号
徐赟博 2020211035

任 课 教 师
卜晨阳

2022 ~2023 学年第 一 学期

第1页共8页
《算法设计与分析》实验报告

说 明
实验报告是关于实验教学内容、过程及效果的记录和总结,因此,
应注意以下事项和要求:
1.实验报告要求:格式规范,语言表达清楚,数据和程序真实。
并能够理论联系实际,认真分析实验中出现的问题与现象,总结经
验。
2.每位同学应独立完成实验报告的撰写,严禁抄袭或拷贝,否
则,一经查实,按作弊论取,并取消理论课考试资格。
3. 可根据实际需要调整每个单元格的篇幅。
4. 请按照要求填写实验报告。算法源代码请放置在附录中。

第2页共8页
《算法设计与分析》实验报告

动态规划最长递增子序列实验报告

——实验序号_ 1__
徐赟博 2020211035
计算机与信息学院(人工智能)学院 智能科学与技术 20-1 班
摘 要:最长递增子序列(Longest Increasing Subsequence, LIS)问题是计算机算法学、随机矩阵理论、表
示理 论、组合数学和生物信息学领域的典型问题之一。本文利用了动态规划策略完成了平台作业的最
长递增子序列的实验任务。
关键词:最长递增子序列;动态规划

引言
最长递增子序列(Longest Increasing Subsequence, LIS)问题是计算机算法学、随机矩
阵理论、表示理论、组合数学和生物信息学领域的典型问题之一。最长递增子序列问题就是
要求序列 L 的一个长度最长的递增子序列。目前,最长递增子序列问题已经被广泛研究。

动态规划是求解具有最优子结构性质的最优化 问题的有效算法设计策略之一,其基本思
想是将规模为 n 的问题分解成若干个子问题,这些子问题往往不是互相独立的、而是重叠
的,且满足最优子结构;每求解出一个子问题,就将其答案保存到数组中,从而避免重叠
子问题的多次计算;最后以自底 向上的方式从子问题的解得到原问题的解。

1 问题背景和相关工作介绍
1.1 题目内容和要求

任务描述 本关任务:掌握动态规划算法思想,并能利用动态规划算法思想解决最长递增
子序列(非连续)问题:

由 n 个正整数组成的序列,从该序列中删除若干个整数,使得剩下的整数组成单调递增
子序列,求最长的单调递增子序列并输出(测试数据保证有唯一解)。

1.2 问题背景介绍

动态规划的基本概念 动态规划(Dynamic Programming)是求解分阶段决策过程最优化


问题的数学方法。动态规划算法处理的对象是多阶段决策问题的最优值。 多阶段决策问题
是指这样的一类特殊的活动过程: 问题可以分解成若干相互联系的阶段,在每一个阶段都
要做出决策,形成一个决策序列,该决策序列也称为一个策略。对于每一个决策序列,可
以在满足问题的约束条件下用一个数值函数(即目标函数)的值来衡量该策略的优劣。多
阶段决策问题的最优化目标是获取导致问题最优值的最优决策序列(最优策略),即得到
最优解。

1.3 已有的相关工作

最长递增子序列问题目前有两种基础的解法,一种是二分查找,另一种是动态规划。

第3页共8页
《算法设计与分析》实验报告

二分查找思想:

原始数组为 A, 建立一个辅助数组 B, 变量 end 用来记录 B 数组末尾元素的下标

遍历 A 中的所有的元素 x = A[i]

如果 x > B 的末尾元素,则将 x 追加到 B 的末尾,end+=1

如果 x < B 的末尾元素,则利用二分查找,寻找 B 中第一个大于 x 的元素,并用 x 进行替


换 e.g. x= 4 B=[1,3,5,6] ==> B=[1,3,4,6]

遍历结束之后,B 的长度则为最长递增子序列的长度

动态规划思想:

假设长度为 n 的数组 A={a0,a1,..,an} , 以 ai 元素结尾的最长递增子序列为 Li ,

则当 j<i<n 且 ai>aj ,Li=max(Lj+1,Li) , Li 的初始值为 1.

初始化长度为 n=6 的数组 L, Li 表示以 ai 结尾的最长递增子序的长度,即 L={1,1,1


,1,1,1}

遍历 i , 计算 Li

对于每个 i, 需要遍历 j ( 0< j < i)

如果 A[i]>A[j] 则 L[i]=max(L[j]+1,L[i]) , 即 A[i] 元素可以接到 L[j]对应的 LIS 的末尾,


因此长度加 1, max 是为了保证 L[i]永远是最大值; 否则 L[i]=1

得到数组 L , 获取其中的最大值,则为最长递增子序列的长度。

时间复杂度 : O(n2)

2 算法介绍
2.1 解题思路

实验中采用的是动态规划的思路。

设长度为 N 的数组为{a0,a1, a2, ...an-1),则假定以 aj 结尾的数组序列的最长递增子序列


长度为 L(j),则 L(j)={ max(L(i))+1, i<j 且 a[i]<a[j] }。也就是说,我们需要遍历在 j 之前的所
有位置 i(从 0 到 j-1),找出满足条件 a[i]<a[j]的 L(i),求出 max(L(i))+1 即为 L(j)的值。最后,
我们遍历所有的 L(j)(从 0 到 N-1),找出最大值即为最大递增子序列。时间复杂度为
O(N^2)。

第4页共8页
《算法设计与分析》实验报告

2.2 算法伪代码和细节介绍

按课堂讲述建立一个二维数组,从前到后遍历两个字符串中的内容,如果相同进行自加,
如果不同就取周围的最大值。

3 实验
3.1 实验设置

实验工具:算法分析与设计作业平台

参数设置:实验平台的测试样例

3.2 实验结果与分析

测试用例和输入输出如下图所示。

第5页共8页
《算法设计与分析》实验报告

实验结果

从平台反映的实验结果来看,我们完好的完成了实验任务。

4 结语
通过本次实验,比较好的将上课所学到的内容和实际编程结合在了一起。上课讲的利用
二维数组的方式存储扫描两个序列中子序列的长度的做法,在脑海中理解需要费点劲,但
是用代码做出来就会比较容易而且方便理解。但是,该实验还有继续做下去改进的地方,
比如可以使用二分搜索的方式,网络上的博客也提供了一种使用 DP+二分搜索可以达到
Nlogn 复杂度的做法。

参考文献

[1] 乔明泽,宋传鸣.最长递增子序列问题研究[J].软件,2019,40(07):31-34.

[2] 奚雨新.分治算法与动态规划算法研究[J].长江信息通信,2021,34(06):44-46.

[3] 李强. 动态规划算法时间效率优化策略研究[D].中南民族大学,2015.

[4] 张爱华,郭喜跃,陈前军.动态规划算法分析与研究[J].软件导刊,2014,13(12):68-69

附录 A:感想、体会、建议
本门课程既有理论推导部分,也有实际的上机编程部分。两者是相互促进的。就本门课而言,
学会实际动手编程可以很好的促进脑海中对于算法的理解程度,而如果但是对着 PPT 去推演的
话,我个人认为是相对比较难而且死板的。所以我认为本节课的形式相当不错,就是老师上课
讲的算法分析部分,听起来比较吃力。

第6页共8页
《算法设计与分析》实验报告

源代码
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>

using namespace std;

const int maxn = 101;

int main() {
int n;
cin >> n;
int answer[maxn];
memset(answer, 0, sizeof(answer));
for(int i = 1; i <= n; i++){
cin >> answer[i];
}
int id[maxn];
memset(id, 0, sizeof(id));
int dp[maxn];
for(int i = 1; i <= n; i++) dp[i] = 1;
int max_index = 0;
int ans = 1;
for(int i = n - 1; i >= 1; i--){
for(int j = i + 1; j <= n; j++){
if(answer[i] < answer[j] && dp[j] + 1 > dp[i]){
dp[i] = dp[j] + 1;
id[i] = j;
}
}
if(dp[i] > ans){
max_index = i;
ans = dp[i];
}
}
int i = max_index;
cout << answer[i];
while(id[i]){
i = id[i];
cout << " " << answer[i];
}
cout << endl;
第7页共8页
《算法设计与分析》实验报告

第8页共8页

You might also like