20201003008陆启康算法设计与分析第二次上机之动态规划实验报告
1.1 问题描述
7-2 单调递增最长子序列 (25 分)
设计一个O(n2)时间的算法,找出由n个数组成的序列的最长单调递增子序列。
输入格式:
输入有两行: 第一行:n,代表要输入的数列的个数 第二行:n个数,数字之间用空格格开
输出格式:
最长单调递增子序列的长度
输入样例:
在这里给出一组输入。例如:
5
1 3 5 2 9
*结尾无空行
输出样例:
在这里给出相应的输出。例如:
4
*结尾无空行
1.2 算法描述:
该算法属于自底向上的对问题进行求解的算法,由于题目没有要求,该算法内并不包含REC表格,故并没有对最长单调递增子序列的具体序列进行求解。该算法以以第n个数结尾的最长单调递增子序列为子问题,从左向右填充表格。
初始化:以第一个数结尾的最长单调递增子序列长度为1,故a[0] = 1;
当第n个数大于第i个数时(i<=n, i- - ),n的最长单调递增子序列长度等于i的最长的最长单调递增子序列的长度加一。
填充完表格后,找出表格中最大的数进行输出。
1.3 问题求解:
#include<iostream>
using namespace std;
int d[10000];
int zeng(int a[],int b)
{
d[0] = 1;
int i,n,m,max,j;
i = 0;
m = 0;
max = 0;
for (i; i < b; i++)
{
for (n = i-1; n >= 0; n--)
{
if(a[n] < a[i])
{
if (d[i] < d[n] + 1)
{
d[i] = d[n] + 1;
}
}
}
}
for(int u = 0; u <= b; u++)
{
if(d[u] >= max)
{
max = d[u];
}
}
return max;
}
int main()
{
int a[10000];
int t,p;
cin >> t;
for(int y = 0; y < t; y++)
{
cin >> a[y];
d[y] = 1;
}
p = zeng(a,t) ;
cout << p ;
}
1.1.1 根据最优子结构性质,列出递归方程式,
If a[n]>=a[n-1]
{
a[n] = a[n-1] + 1
}
If a[n]<a[n-1]
{
a[n] = a[n-1]
}
1.1.2 给出填表法中表的维度、填表范围和填表顺序。
一维数组
范围:d[0]-d[n-1]
顺序:从右到左
1.1.3 分析该算法的时间和空间复杂度
时间复杂度:O(n2)
空间复杂度:O(n2)
1.3 心得体会(对本次实践收获及疑惑进行总结)
这道题非常好
看起来很简单
做起来很难
动态规划在解决很多实际问题上非常有帮助