算法第3章作业

1.

 动态规划所处理的问题是一个多阶段决策问题,一般由初始状态开始,通过对中间阶段决策的选择,达到结束状态。这些决策形成了一个决策序列,同时确定了完成整个过程的一条活动路线(通常是求最优的活动路线)。如图所示。动态规划的设计都有着一定的模式,一般要经历以下几个步骤。
┌───┐┌───┐┌───┐
初始状态→│决策1│→│决策2│→…→│决策n│→结束状态
└───┘└───┘└───┘

 

2. 编程题 (1)

7-1 单调递增最长子序列 (20 分)

设计一个O(n2)时间的算法,找出由n个数组成的序列的最长单调递增子序列。

思考:首先我考虑假如求A[1],A[2],…,A[i]的最长非降子序列的长度,其中i<N, 那么上面的问题变成了原问题的一个子问题(问题规模变小了,可以让i=1,2,3等来分析) 然后我们定义d(i),表示前i个数中以A[i]结尾的最长非降子序列的长度。可以估计到这个d(i)就是我们要找的状态。 如果我们把d(1)到d(N)都计算出来,那么最终我们要找的答案就是这里面最大的那个。

想要求d(i),就把i前面的各个子序列中, 最后一个数不大于A[i]的序列长度加1,然后取出最大的长度即为d(i)。 当然,有可能i前面的各个子序列中最后一个数都大于A[i],那么d(i)=1, 即它自身成为一个长度为1的子序列。

方法实现:

int lis(int A[], int n){

    int *d = new int[n];

    int len = 1;

    for(int i=0; i<n; ++i){

        d[i] = 1;

        for(int j=0; j<i; ++j)

            if(A[j]<=A[i] && d[j]+1>d[i])//找到最后一个小于i且满足递增序列的那个数 

                d[i] = d[j] + 1;//找到后那个书的最长序列加一 

        if(d[i]>len) len = d[i];//若找到 ,将新的序列长度赋值给len 

    }

    delete[] d;

    return len;

}

编程题(2)

7-2 租用游艇问题

思考:动态规划:
定义f[i][j]为站点i到站点j的最少租金:
rent[i][j] = min { rent[i][k] + rent[k][j] }
其中 i<k<j, 0<=i,j<=n-1
则最少租金为 rent[0][n-1]

方法实现:

#include<iostream>

using namespace std;

 

int rent[1000][1000];

 

int A(int n){

    int t;

    for(int i=n-2; i>=1; i--){

        for(int j=i+2; j<=n; j++){

            for(int k=i+1; k<j; k++){

                t = rent[i][k] + rent[k][j];

                if(t<rent[i][j]){

                    rent[i][j] = t;

                }

            }

        }

    }

    return rent[1][n];

}

 

int main(){

    int n;

    cin>>n;

    for(int i=1; i<n; i++){

        for(int j=i+1; j<=n; j++){

            cin>>rent[i][j];

            /*输入格式:1->2, 1->3 

                              2->3  */

        }

    }

    cout<<A(n);

    

}

3.结对编程思考

最近与同伴共同编程时间较少,虽有线上交流,但缺少更多线下的讨论和合作。以后需注意。

 

posted @ 2018-10-28 19:42  陳泽博Czmichael  阅读(246)  评论(0编辑  收藏  举报