寒假集训作业(9)——动态规划初步(2)

题目可参见:http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=1299

最长上升子序列

采用栈实现(思想是转载的)。先让第一个元素入栈。第二个元素先行与栈顶判断:

1.如果该元素与栈顶元素相比,比栈顶元素大,那么让它入栈;

2.如果该元素与栈顶元素相比,比栈顶元素小,那么从栈内检索第一个比该元素大的元素并用该元素替换之。(采用二分查找,该思想仍需学习)

3.最后剩余的栈元素个数就是最长子序列,元素就是最长子序列。这句话是错误的,应该改为,这是最长上升子序列之一,因为有可能有多个上升的子序列,他们的长度是相等的。

4.至于为什么它这么做的结果是正确的,我想可以解释如下:我们每次入栈的本身就是上升的子序列,然后替换的元素是比它大的第一个元素,而被替换的元素后面一定是上升的,那么这整体又构成了一个上升序列,替换之后元素个数并不改变。

#include <iostream>
#define SIZE 1001

using namespace std;

int main()
{
    int i, j, n, top, temp;
    int stack[SIZE];
    cin >> n;

    top = 0;
    stack[0] = -1;//retain the first element
    for (i = 0; i < n; i++)
    {
        cin >> temp;
        if (temp > stack[top])//push when greater
        {
            stack[++top] = temp;
        }
        else
        {
            int low = 1, high = top;
            int mid;
            while(low <= high)//binary search
            {
                mid = (low + high) / 2;
                if (temp > stack[mid])
                {
                    low = mid + 1;
                }
                else
                {
                    high = mid - 1;
                }
            }
            stack[low] = temp;//replace the first-greater element
        }
    }
    cout << top << endl;//the length is the answer, and the elements are the sub-sequence...
    //system("pause");
    return 0;
}

至于如何用STL实现,我觉得还是等C++ Prime还有STL介绍这两本书到了之后再说吧。贺贺说的很对,工具不够灵活,C语言就是强悍在它能够灵活地编写算法。使用STL只是在一些工具的堆砌而已,不靠谱。



数字三角形:http://acm.hdu.edu.cn/showproblem.php?pid=2084

数字三角形问题

自底向上解决它!

寒假集训作业(9)——动态规划初步(2)_第1张图片
我们把它换一下格式:
寒假集训作业(9)——动态规划初步(2)_第2张图片
上图比较详细地描述了该过程:
#include <iostream>

using namespace std;

int main()
{
    int c;
    int a[110][110];
    cin>>c;
    while(c--)
    {
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=i;j++)
            {
                cin>>a[i][j];
            }
        }
        for(int i=n;i>0;i--)
        {
            for(int j=1;j<=i;j++)
            {
                if(a[i][j]>a[i][j+1])
                {
                    a[i-1][j]+=a[i][j];
                }
                else
                {
                    a[i-1][j]+=a[i][j+1];
                }
            }
        }
        cout<<a[1][1]<<endl;
    }
}


你可能感兴趣的:(理论学习,ACM题解报告,集训作业)