本文索引目录:

一、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数组。

要确认当前位置,也就需要定义成二维数组,第一个指定为行,第二个指定为具体列。

第二步,我们需要确定动态方程,很明显我们知道:

方程为:dp[i][j] = temp[i][j] + max(dp[i+1][j],dp[i+1][j+1])

以最后两列为例,模拟动规过程:

可以很明显的发现,当下面两格相比,取出最大值,加上自己本身,就是当前的dp值,依照这个思路

我们可以把整个dp过程模拟完成:

到此模拟完成,我们可以很清楚的看到,我们最终想要的答案,就在最顶层,dp[1][1]中,我们只需要固定输出这个值即可得到答案。

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

完整代码展示如下:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int n,temp[][],ans = ;
  4. int main()
  5. {
  6. /* input */
  7. cin>>n;
  8. for(int i = ;i<=n;i++)
  9. for(int j = ;j<=i;j++)
  10. cin>>temp[i][j];
  11.  
  12. /* 动规转移方程: dp[i][j] = temp[i][j] + max(dp[i+1][j],dp[i+1][j+1]);*/
  13.  
  14. /* down to up */
  15. for(int i = n;i>;i--)
  16. for(int j = ;j<=i;j++)
  17. temp[i][j] = temp[i][j] + max(temp[i+][j],temp[i+][j+]);
  18.  
  19. /* answer */
  20. cout<<temp[][];
  21. }

  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代码如下:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int n,temp[],dp[],flag = ,k;
  4. int main()
  5. {
  6. /* input */
  7. cin>>n;
  8. for(int i = ;i<=n;i++)
  9. {
  10. cin>>temp[i];
  11. if(temp[i] >=) flag = ;
  12. }
  13.  
  14. /* dp[i]:1-i中最大子段和
  15. k: k从0到i加和大于0的子段,遇到子段小于0的扔掉重新开始计长度*/
  16. for(int i = ;i<=n;i++)
  17. {
  18. if(k>) k += temp[i];
  19. else k=temp[i];
  20. dp[i] = max(dp[i-], k);
  21. }
  22.  
  23. /* answer */
  24. if(flag == ) cout<<;
  25. else cout<<dp[n];
  26. return ;
  27. }

  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代码如下:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int dp[][];
  4. char a[];
  5. char b[];
  6. int minval(int a,int b,int c){
  7. int temp = max(a,b);
  8. return max(temp,c);
  9. }
  10. int LCS(char *a,char *b)
  11. {
  12. memset(dp,,sizeof(dp));
  13. int lena=strlen(a);
  14. int lenb=strlen(b);
  15. for(int i=;i<=lena;i++)
  16. {
  17. for(int j=;j<=lenb;j++)
  18. {
  19. if(a[i-]==b[j-])
  20. dp[i][j]=minval(dp[i-][j],dp[i][j-],dp[i-][j-]+);
  21. else
  22. dp[i][j]=minval(dp[i-][j],dp[i][j-],dp[i-][j-]);
  23. }
  24. }
  25. return dp[lena][lenb];
  26. }
  27.  
  28. int main()
  29. {
  30. cin>>a;
  31. getchar();
  32. cin>>b;
  33. int maxss =max(strlen(a),strlen(b));
  34.  
  35. cout<<maxss-LCS(a,b);
  36.  
  37. return ;
  38. }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

『嗨威说』算法设计与分析 - PTA 数字三角形 / 最大子段和 / 编辑距离问题(第三章上机实践报告)的更多相关文章

  1. 『嗨威说』算法设计与分析 - PTA 程序存储问题 / 删数问题 / 最优合并问题(第四章上机实践报告)

    本文索引目录: 一.PTA实验报告题1 : 程序存储问题 1.1 实践题目 1.2 问题描述 1.3 算法描述 1.4 算法时间及空间复杂度分析 二.PTA实验报告题2 : 删数问题 2.1 实践题目 ...

  2. 『嗨威说』算法设计与分析 - 动态规划思想小结(HDU 4283 You Are the One)

    本文索引目录: 一.动态规划的基本思想 二.数字三角形.最大子段和(PTA)递归方程 三.一道区间动态规划题点拨升华动态规划思想 四.结对编程情况 一.动态规划的基本思想: 1.1 基本概念: 动态规 ...

  3. 『嗨威说』算法设计与分析 - 贪心算法思想小结(HDU 2088 Box of Bricks)

    本文索引目录: 一.贪心算法的基本思想以及个人理解 二.汽车加油问题的贪心选择性质 三.一道贪心算法题点拨升华贪心思想 四.结对编程情况 一.贪心算法的基本思想以及个人理解: 1.1 基本概念: 首先 ...

  4. 『嗨威说』算法设计与分析 - STL中Sort函数的实现原理初探

    本文索引目录: 一.对Sort算法实现的个人阅读体会 二.Sort算法使用的三个排序算法的优点介绍 2.1 插入排序的优缺点 2.2 堆排序的优缺点 2.3 快速排序的优缺点 2.4 新的结合排序—— ...

  5. 『嗨威说』算法设计与分析 - 回溯法思想小结(USACO-cha1-sec1.5 Checker Challenge 八皇后升级版)

    本文索引目录: 一.回溯算法的基本思想以及个人理解 二.“子集和”问题的解空间结构和约束函数 三.一道经典回溯法题点拨升华回溯法思想 四.结对编程情况 一.回溯算法的基本思想以及个人理解: 1.1 基 ...

  6. 『嗨威说』常见的C++函数模板整理(一)

    开学两天,身上的职责直接变为两个班班长,三个小组组长,哇这事情估计够我忙活了,想躲都躲不掉啊,看来我还是真招人推荐各种管理职务啊,以后要是有人推荐我当经理啊领导啊该多好哈哈哈哈.记得今天奶奶生日,很开 ...

  7. 【技术文档】《算法设计与分析导论》R.C.T.Lee等·第7章 动态规划

    由于种种原因(看这一章间隔的时间太长,弄不清动态规划.分治.递归是什么关系),导致这章内容看了三遍才基本看懂动态规划是什么.动态规划适合解决可分阶段的组合优化问题,但它又不同于贪心算法,动态规划所解决 ...

  8. 算法设计与分析 - AC 题目 - 第 5 弹(重复第 2 弹)

    PTA-算法设计与分析-AC原题 - 最大子列和问题 (20分) 给定K个整数组成的序列{ N1, N2, ..., NK },“连续子列”被定义为{ Ni, Ni+, ..., Nj },其中 ≤i ...

  9. 算法设计与分析 - AC 题目 - 第 2 弹

    PTA-算法设计与分析-AC原题7-1 最大子列和问题 (20分)给定K个整数组成的序列{ N1, N2, ..., NK },“连续子列”被定义为{ Ni, Ni+1, ..., Nj },其中 1 ...

随机推荐

  1. zookeeper集群部署问题排查记录

    今天在三台虚拟机搭建zookeeper集群,一直连不通,然后进行了几个小时的斗争,做个记录. 具体部署方式网上有很多, 不在赘述.产生连接不同的问题主要有以下几个方面: 1.仔细检查配置文件. 是否有 ...

  2. ConcurrentHashMap 的工作原理及代码实现

    ConcurrentHashMap采用了非常精妙的"分段锁"策略,ConcurrentHashMap的主干是个Segment数组.Segment继承了ReentrantLock,所 ...

  3. FreeSql (十八)导航属性

    导航属性是 FreeSql 的特色功能之一,可通过约定配置.或自定义配置对象间的关系. 导航属性有 OneToMany, ManyToOne, ManyToMany, OneToOne, Parent ...

  4. cobbler高可用方案

    一.环境准备 主网IP 私网IP 主机名 角色 VIP 10.203.178.125 192.168.10.2 cnsz22VLK12919 主 10.203.178.137,192.168.10.1 ...

  5. selenium WebDriver 截取网站的验证码

    在做爬虫项目的时候,有时候会遇到验证码的问题,由于某些网站的验证码是动态生成的,即使是同一个链接,在不同的时间访问可能产生不同的验证码, 一 刚开始的思路就是打开这个验证码的链接,然后通过java代码 ...

  6. c语言的数据类型,运算符,存储类型

    [1词法符号]1. 关键字:32个1) 存储类型:决定(设备)变量的存储位置auto(自动型).extern(外部引用) static(静态型) register(寄存器类型)2) 数据类型:决定设备 ...

  7. Django中自定义模型管理器(Manager)及方法

    1.自定义管理器(Manager) 在语句Book.objects.all()中,objects是一个特殊的属性,通过它来查询数据库,它就是模型的一个Manager.每个Django模型至少有一个ma ...

  8. Mysql学习笔记整理之引擎

    mysql的引擎: myisam引擎 Mysql 5.5之前默认的存储引擎 数据.索引分别存储 (数据物理磁盘---索引物理磁盘) .MYD 存储数据                      表级索 ...

  9. select2 分组后的选项无法被选中

    在使用select2组件的过程中发现分组下的选项无法选中,与分组在同一级的选项可以被选中! 1.所用select2版本select2-4.0.32 2.HTML代码: <input id=&qu ...

  10. 数据结构之二叉树篇卷三 -- 二叉树非递归遍历(With Java)

    Nonrecursive Traversal of Binary Tree First I wanna talk about why we should <code>Stack</c ...