×

小刀网

wwwwuyuetian123com(www五月天国产)

访客 访客 发表于2022-05-05 13:01:00 浏览813 评论1

1人参与发表评论

动态规划(Dynamic++ Programming,简称DP),虽然抽象后进行求解的思路并不复杂,但具体的形式千差万别,找出问题的子结构以及通过子结构重新构造最优解的过程很难统一,并不像回溯法。为了解决动态规划问题,只能靠多练习、多思考了。本文主要是对一些常见的动态规划题目的收集,希望能有所帮助。难度评级受个人主观影响较大,仅供参考。

动态规划求解的一般思路:

判断问题的子结构(也可看作状态),当具有最优子结构时,动态规划可能适用。

求解重叠子问题。一个递归算法不断地调用同一问题,递归可以转化为查表从而利用子问题的解。分治法则不同,每次递归都产生新的问题。

重新构造一个最优解。

备忘录法:

动态规划的一种变形,使用自顶向下的策略,更像递归算法。

初始化时表中填入一个特殊值表示待填入,当递归算法第一次遇到一个子问题时,计算并填表;以后每次遇到时只需返回以前填入的值。

实例可以参照矩阵链乘法部分。

1.硬币找零

难度评级:★

假设有几种硬币,如1、3、5,并且数量无限。请找出能够组成某个数目的找零所使用最少的硬币数。

解法:

用待找零的数值k描述子结构/状态,记作sum[k],其值为所需的最小硬币数。对于不同的硬币面值coin[0...n],有sum[k] = min(sum[k-coin[0]] , sum[k-coin[1]], ...)+1。对应于给定数目的找零total,需要求解sum[total]的值。

typedef struct {

int nCoin; //使用硬币数量

//以下两个成员是为了便于构造出求解过程的展示

int lastSum;//上一个状态

int addCoin;//从上一个状态达到当前状态所用的硬币种类

} state;

通过sum[total].lastSum和sum[total].addCoin,很容易通过循环逆序地或者编写递归调用的函数正序地输出从结束状态到开始状态使用的硬币种类。以下各题输出状态转换的方法同样,不再赘述。下面为了方便起见,有的题没有在构造子结构的解时记录状态转换,如果需要请类似地完成。

扩展:

(1)一个矩形区域被划分为N*M个小矩形格子,在格子(i,j)中有A[i][j]个苹果。现在从左上角的格子(1,1)出发,要求每次只能向右走一步或向下走一步,最后到达(N,M),每经过一个格子就把其中的苹果全部拿走。请找出能拿到最多苹果数的路线。

难度评级:★

分析:

这道题中,当前位置(i,j)是状态,用M[i][j]来表示到达状态(i,j)所能得到的最多苹果数,那么M[i][j] = max(M[i-1][j],M[i][j-1]) + A[i][j] 。特殊情况是M[1][1]=A[1][1],当i=1且j!=1时,M[i][j] = M[i][j-1] + A[i][j];当i!=1且j=1时M[i][j] = M[i-1][j] + A[i][j]。

求解程序略。

修改自:https://www.cnblogs.com/wuyuegb2312/p/3281264.html

感谢各位支持,点击屏幕右上角的【关注】每天文章不落下。感激不尽!

本头条号文章分类目录(精心整理)

群贤毕至

访客
南殷绾痞 南殷绾痞2024-02-09 06:24:33 | 回复 M[i][j] = M[i-1][j] + A[i][j]。求解程序略。修改自:https://www.cnblogs.com/wuyuegb2312/p/3281264.html感谢各位支持,点击屏幕右上角的【关注】每天文章不落下。感激不尽!本头条号文章分类