dp的初步理解

dp的理解

dp的正规解释是:动态规划(英语:Dynamic programming,DP)是一种在数学、计算机科学和经济学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。 动态规划常常适用于有重叠子问题和最优子结构性质的问题,动态规划方法所耗时间往往远少于朴素解法。

动态规划背后的基本思想非常简单。大致上,若要解一个给定问题,我们需要解其不同部分(即子问题),再合并子问题的解以得出原问题的解。 通常许多子问题非常相似,为此动态规划法试图仅仅解决每个子问题一次,从而减少计算量: 一旦某个给定子问题的解已经算出,则将其记忆化存储,以便下次需要同一个子问题解之时直接查表。 这种做法在重复子问题的数目关于输入的规模呈指数增长时特别有用。
动态规划问题的三大性质(也是dp能用的三大条件):
最优子结构性质:如果问题的最优解所包含的子问题的解也是最优的,我们就称该问题具有最优子结构性质(即满足最优化原理)。最优子结构性质为动态规划算法解决问题提供了重要线索。

子问题重叠性质:子问题重叠性质是指在用递归算法自顶向下对问题进行求解时,每次产生的子问题并不总是新问题,有些子问题会被重复计算多次。动态规划算法正是利用了这种子问题的重叠性质,对每一个子问题只计算一次,然后将其计算结果保存在一个表格中,当再次需要计算已经计算过的子问题时,只是在表格中简单地查看一下结果,从而获得较高的效率。

无后效性:将各阶段按照一定的次序排列好之后,对于某个给定的阶段状态,它以前各阶段的状态无法直接影响它未来的决策,而只能通过当前的这个状态。换句话说,每个状态都是过去历史的一个完整总结。这就是无后向性,又称为无后效性。


可能上边的文字看的很麻烦,dp实际上是对求解最优解较好的算法,总结起来,就是求解最优解,和计算一些有重叠的子问题,以及一步步进行不会因为前一步而被影响的问题的一大利器。
动态规划(dp) 实际上是以空间换时间的一种算法,dp在计算过程中需要记录一些子问题的结果, 以避免再进行计算时重复计算,大大节省了时间。
例如数字三角形问题:
有一个由非负整数组成的三角形,第一行只有一个数,除了最下行之外每个数的左下方和右下方各有一个数.
1
3 2
4 10 1
4 3 2 20
从第一行的数开始,每次可以往左下或右下走一格,直到走到最下行,把沿途经过的数全部加起来,如何走才能使得这个和尽量大?
输入:三角形的行数n,数字三角形的各个数(从上到下,从左到右)
输出:最大的和。

#include<iostream>
using namespace std;
int r,a[1050][1050]={};
int main()
{
    cin>>r;
    for(int i=1;i<=r;i++)
    {
    	for(int j=1;j<=i;j++)
    	{
    		cin>>a[i][j];
    	}
    }
   for(int i=r-1;i>=1;i--)
   {
   	for(int j=1;j<=i;j++)
   	{
   		a[i][j]=a[i][j]+max(a[i+1][j],a[i+1][j+1]);
   		//cout<<"a"<<"["<<i<<"]"<<"["<<j<<"]"<<"="<<a[i][j]<<endl;
   	}
   }
   cout<<a[1][1]; 
	return 0;
}

状态转移方程:a[i][j]=a[i][j]+max(a[i+1][j],a[i+1][j+1])
这是一种逆推的方式,当我从后往前推算时,正常的计算就是无后效性,不需要去考虑多种情况。
dp问题最重要的就是找到状态转移方程,这样才能一步步的进行推导和保存。

  • 21
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值