动态规划算法学习(适合初学的选手)

动态规划算法通过组合子问题求解原问题,避免重复计算,提高效率。本文以钢条切割和最长公共子序列问题为例,详细解释动态规划的原理和应用,包括递归、备忘录和自底向上法的实现,旨在为初学者提供清晰的理解。
摘要由CSDN通过智能技术生成

摘要
动态规划(Dynamic programming)通过组合子问题来来求解原问题(在此处,我们不妨将"programming"理解为一种表格,用于记录上一步执行的结果)。动态规划算法对每个子问题只求解一次(而递归算法重复求解相同的子问题,因而效率非常低),并将其解保存在一个表格中,从而不必每次重复求解相同子问题,动态规划算法效率大大高于递归算法就得益于此。动态规划算法在数学、管理科学、计算机科学、经济学和生物信息学中广泛应用。本文以钢条切割问题和最长公共子序列问题为例讲解动态规划算法。
一. 钢条切割问题
将一段钢条切割成若干段,每段钢条长度为整数,每段钢条价格如下表所示,若要获得最大收益应如何切?
钢条价格表
此处参考《算法导论》中的叙述(见下图)
在这里插入图片描述
一般地,对于rn(n≥1),用下式表示收益:
rn=max(pn,r1+rn-1,r2+rn-2,…,rn-1+r1)
上式可进一步简化为 rn=max(pi+rn-i), 其中1≤i≤n.此式称为状态转移方程,由此可有三种方案解决,分别为:自顶向下递归实现、带备忘的自顶向下法(top-down with memoization)和自底向上向上法(bottom-up method),其中后两种方案属于动态规划动态规划方法。下面分别用代码实现之:
1.递归方法:

#include <iostream>
#include<algorithm>
using namespace std;
#define N 100
int CUT_ROD(int p[N],int n)
{
   
 if(n==0)
  return 0;
 int q=-1;
 for(int i=1;i<=n;i++)
  q=max(q,p[i]+CUT_ROD(p,n-i));
 return q;
}
int main()
{
   
 int v[N]={
   0,1,5,8,9,10,17,17,20,24,30};
 cout<<"钢条切割的最大收益为:"<<endl;
 cout<<CUT_ROD(v,10)<<endl;
 return 0;
}

2.带备忘的自顶向下法

#include <iostream>
#include <algorithm>
using namespace std;
#define N 100
int MEMOIZED_CUT_ROD_AUX(int p[N],int n,int r[N])  //带备忘机制的递归函数
{
   
 int q;
 if(r[n]>=0)
  return r[n];
 if(n==0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值