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 心得体会(对本次实践收获及疑惑进行总结)

这道题非常好

看起来很简单

做起来很难

动态规划在解决很多实际问题上非常有帮助

posted @ 2021-10-26 09:19  我不要摆烂  阅读(103)  评论(0编辑  收藏  举报