PTAデジタル三角形/最大サブセグメント及び/編集距離問題(第III章ハンズレポート) - アルゴリズムの設計と解析「魏ちょっと言いました」

引用ディレクトリ:

、PTAラボレポートタイトル1:デジタル三角形

  1.1実践トピック

  問題の1.2説明

  1.3アルゴリズムの説明

  時間と空間解析の1.4アルゴリズムの複雑さ

二、PTAのテストは、質問2報告:最大のサブセグメントと

  2.1実践トピック

  問題の2.2説明

  2.3アルゴリズムの説明

  時間と空間解析の2.4アルゴリズムの複雑さ

三、PTAの試験報告書3質問:編集距離の問題

  3.1実践トピック

  問題の3.2説明

  3.3アルゴリズム記述

  時間と空間解析の3.4アルゴリズムの複雑さ

第四に、実験的な経験(収穫と疑問の実践)

 

 

、PTAラボレポートタイトル1:デジタル三角形

  1.1練習タイトル:

 

  問題の1.2説明:

     タイトルあなたの三角形を与えるために、ステム旨(すなわち、実際に、矩形、三角形、または上三角パターンモードの半分)は、最大のデジタル和が経過するように、端部の上から最適なルートを計算する必要があります。

 

  1.3アルゴリズムの説明:

この質問は、サブ問題が重なっている動的計画法を使用することが明らかに必要であるので、我々は、動的方程式を転送することにより、この問題を確認する必要があります。

私たちは、シミュレーションによって見つけることができる、最高のウォーキング・パスの例は以下のとおりです。

 明らかに、我々は、動的プログラミングの最適な経路を見つけるために、貪欲アルゴリズムによって、この質問を行うことができないことがわかります。

まず、我々はDPの配列を作成する必要があり、定義された配列を意味するDPは次のとおりです。現在の位置の合計が経験してきたように、我々は、配列のDPを初期化します。

現在位置を確認するために、2次元配列を定義する必要があり、最初の行として指定され、第2列は、具体的に指定されています。

 第二に、我々は、我々が知っていることは明らかである運動方程式を決定する必要があります。

式:DP [I] [J] = TEMP [I] [J] + MAX(DP [I + 1] [j]は、DP [I + 1] [J + 1])

最後の2では、例えば、動的な規制プロセスをシミュレートします:

 明らかに、次の二つのセルと比較して、最大を削除することが判明し、プラス自体、この考え方に基づいて、DPの現在の値であることができます

私たちは、シミュレーションが終了したDPプロセス全体を置くことができます。

このシミュレーションは完了し、我々は最終的には、単にトップレベルで、DPにお答えしたいことをはっきりと見ることができます[1] [1]、我々は唯一の答えを得るために、固定出力値を必要とします。

第三步,确认我们的填表顺序,从以上的分析角度可以知道,dp方程中当前dp依赖于当前位置的下一行同列以及下一行同列+1的位置,所以需要从下往上填表,分析完毕,按着这个思路敲出代码即可,

完整代码展示如下:

#include<bits/stdc++.h>
using namespace std;
int n,temp[105][105],ans = 0;
int main()
{
    /* input */
    cin>>n;
    for(int i = 1;i<=n;i++)
        for(int j = 1;j<=i;j++)
            cin>>temp[i][j];
    
    /* 动规转移方程: dp[i][j] = temp[i][j] + max(dp[i+1][j],dp[i+1][j+1]);*/
        
    /* down to up */
    for(int i = n;i>0;i--)
        for(int j = 1;j<=i;j++)
            temp[i][j] = temp[i][j] + max(temp[i+1][j],temp[i+1][j+1]);

    /* answer */    
    cout<<temp[1][1];    
 } 

 

  1.4  算法时间及空间复杂度分析:

   整体算法上看,动态规划是不计算重复子问题,并优化计算过程,防止计算重复,经过分析可知,我们需要O(n^2)时间初始化dp数组,需要O(1/2 * n^2)的时间进行填表,最后输出,总的来看时间复杂度为O(n^2)。

   动态规划需要用到辅助空间二维数组进行填表,表的大小根据问题规模确定,因此空间复杂度是O(n^2)。

 

 

二、PTA实验报告题2 : 最大子段和

  2.1  实践题目:

 

  2.2  问题描述:

    第二题是动态规划的小小压缩版本,题意是说给一段序列,求怎么取一小段,使得加和数最大,也即最大子段和问题。

 

  2.3  算法描述:

    首先,分析题目选择相应算法,虽然这章都是在学动态规划,但是在平时拿到题目的时候,我们是不知道这是动态规划的,所以需要分析问题,一般这种求最值问题,常常先考虑贪心能否使用,可以发现这道题是可以使用贪心算法的,所以我也使用贪心算法写了一次,但是呢鉴于题目要求需要O(n)的时间复杂度,因此优先考虑动态规划啦。

      第二,初始化dp数组,定义dp数组dp[i]为从1到i中最大的子段和。

       第三,动态规划转移方程,明显可以知道:dp[ i ] = max( dp[ i-1 ] , k ) ; k 为从0-i的加和大于0的子段,一旦小于0就从当前位置重新计段长。

    模拟过程如下:

   因此我们就可以很愉快的写出代码啦。AC代码如下:

#include<bits/stdc++.h>
using namespace std;
int n,temp[10005],dp[10005],flag = 0,k;
int main()
{
    /* input */
    cin>>n;
    for(int i = 1;i<=n;i++)
    {
        cin>>temp[i];
        if(temp[i] >=0) flag = 1;
    }

    /*    dp[i]:1-i中最大子段和
        k: k从0到i加和大于0的子段,遇到子段小于0的扔掉重新开始计长度*/
    for(int i = 1;i<=n;i++)
    {
        if(k>0) k += temp[i];
        else k=temp[i];        
        dp[i] = max(dp[i-1], k);
    }
    
    /* answer */ 
    if(flag == 0) cout<<0;
    else cout<<dp[n];
    return 0;
}

 

  2.4  算法时间及空间复杂度分析:

    算法复杂度跟题目要求一致,时间复杂度为O(n)。

    空间复杂度需要一个一维数组dp,因此空间复杂度也是O(n)

 

 

三、PTA实验报告题3 : 编辑距离问题

  3.1  实践题目:

 

  3.2  问题描述:

    该题目为:题目意思是给定两端英文序列,要求将A序列变成B序列,可以通过对A进行删除、插入、更换任意字符,得到B序列,要求以最少步骤为准。

 

  3.3  算法描述:

    这道题我和三木在写的时候第一次没有写出来,三木想到一个绝佳的数学公式,用最大长度字符串长减去LCS即为所求,但是答案WA在了第三点,后来发现存在特例无法解决,所以课后我又换了一种方式,这里我讲解的还不是很好,在一个博客我看到一个非常完整很棒的讲解,贴出来给大家看看吧:

  https://blog.csdn.net/weixin_42681158/article/details/89411572

  我的AC代码如下:

#include<bits/stdc++.h>
using namespace std;
int dp[2005][2005];
char a[2005];
char b[2005];
int minval(int a,int b,int c){
    int temp = max(a,b);
    return max(temp,c);
}
int LCS(char *a,char *b)
{
    memset(dp,0,sizeof(dp));
    int lena=strlen(a);
    int lenb=strlen(b);
    for(int i=1;i<=lena;i++)
    {
        for(int j=1;j<=lenb;j++)
        {
            if(a[i-1]==b[j-1])
                dp[i][j]=minval(dp[i-1][j],dp[i][j-1],dp[i-1][j-1]+1);
            else
                dp[i][j]=minval(dp[i-1][j],dp[i][j-1],dp[i-1][j-1]);
        }
    }
    return dp[lena][lenb];
}

int main()
{
    cin>>a;
    getchar();
    cin>>b;
    int maxss =max(strlen(a),strlen(b));
    
    
    cout<<maxss-LCS(a,b);
    
    return 0;
}

 

  3.4  算法时间及空间复杂度分析:

    由分析易知,时间复杂度和空间复杂度均为O(n^2)

 

 

四、实验心得体会(实践收获及疑惑):

  经过第一次实践合作之后,第二次的实践合作愈发顺利,虽然第三题有一小点WA了,不过还是很合作默契的哈哈。(主要是三木太强了)

简单通过书本和博客总结了一下动态规划的一些基本特点如下:

 ===动态规划问题的特点:

(1)最优化原理:如果问题的最优解所包含的子问题的解也是最优的,就称该问题具有最优子结构,即满足最优化原理。

(2)重叠子问题:即子问题之间是不独立的,一个子问题在下一阶段决策中可能被多次使用到。(该性质并不是动态规划适用的必要条件,但是如果没有这条性质,动态规划算法同其他算法相比就不具备优势)

===动规解题的一般思路:

  动态规划所处理的问题是一个多阶段决策问题,一般由初始状态开始,通过对中间阶段决策的选择,达到结束状态。这些决策形成了一个决策序列,同时确定了完成整个过程的一条活动路线(通常是求最优的活动路线)。

  动态规划的设计都有着一定的模式,一般要经历以下几个步骤。

    初始状态→│决策1│→│决策2│→…→│决策n│→结束状态

  (1)划分阶段:按照问题的时间或空间特征,把问题分为若干个阶段。在划分阶段时,注意划分后的阶段一定要是有序的或者是可排序的,否则问题就无法求解。    

  (2)确定状态和状态变量:将问题发展到各个阶段时所处于的各种客观情况用不同的状态表示出来。当然,状态的选择要满足无后效性。    

  (3)确定决策并写出状态转移方程:因为决策和状态转移有着天然的联系,状态转移就是根据上一阶段的状态和决策来导出本阶段的状态。所以如果确定了决策,状态转移方程也就可写出。但事实上常常是反过来做,根据相邻两个阶段的状态之间的关系来确定决策方法和状态转移方程。    

  (4)寻找边界条件:给出的状态转移方程是一个递推式,需要一个递推的终止条件或边界条件。

 

 

如有错误不当之处,烦请指正。

おすすめ

転載: www.cnblogs.com/WinniyGD/p/11699866.html