动态规划法(一)

一、引言

       “动态规划” (dynamic programming)一词源于研究优化问题的数学理论,动态规划法的发明人贝尔曼(Richard E.Bellman)称,选择“dynamic”一词纯粹是看中了单词本身的魅力,而不是其内在语义。“programming”在研究优化的领域中标识“搜寻最优程序”的意思。


1、重复子问题

     大体上,动态规划法与分治法具有类似的处理方式。使用动态规划法的算法通常先把问题分割成若干子问题,然后求出子问题的答案,最后利用这些答案得出整个问题的最终答案。在动态规划法中,一些子问题的计算结果会用于多个问题的解题过程。因此,在对子问题进行一次计算的情况下,重复利用其结果。为了实现这种方法,需将子问题的答案预先保存到内存,这种保存答案的内存区域就是“缓存”(cache),能够重复利用两次以上的子问题就称为 “重复子问题”。

/*
应用 动态规划法 的最有名的事例之一就是二项式系数的计算
根据二项式系数有如下递归式Cn取r等于Cn-1取r-1加上Cn-1取r 
*/
#include <iostream>

using namespace std;

int bino(int n,int r)
{
	if(r==0 || r==n)
		return 1;
	return bino(n-1,r-1) + bino(n-1,r);
}

int main()
{
	int n,r;
	cout<<"请输入二项式系数n,r"<<endl;
	cin>>n>>r;
	bino(n,r);//利用递归调用计算二项式系数

	cout<<bino(n,r)<<endl;
	system("pause");
	return 0;

}

       bino()内部没有任何循环,因此,可通过计算递归调用的次数来估计bino(n,r)的执行时间,此时需要注意的是,二项式系数的特性会导致很多重复计算。函数的重复调用次数会随着n和r值的增大而呈几何级数增长。如果要计算bino(25,12),就要调用一千万次函数。因此需要想办法避开这些重复计算。当输入值n和r一定的时候,bino(n,r)的返回值也是一定的,利用此原理就可以去掉重复计算。首先定义一个缓存数组,用来保存对不同的n、r组合计算出的结果。每次调用函数时先访问缓存数组,查询有没有相应的结果值,如果有,就返回数组中的值,否则直接计算,计算结果先保存到数组,然后再返回。

      像这种先定义保存函数结果值的空间,然后重复使用结果值的优化方法称为制表。下面代码演示了利用制表计算二项式系数:

/*
应用 动态规划法 的最有名的事例之一就是二项式系数的计算
根据二项式系数有如下递归式Cn取r等于Cn-1取r-1加上Cn-1取r
*/
#include <iostream>
#define MAX 100
using namespace std;

int cache[MAX][MAX];//缓存区域用于存储函数结果值,并初始化为-1

int bino2(int n, int r)
{
	if (r == 0 || r == n)
		return 1;
	if (cache[n][r] != -1)
		return cache[n][r];

	return cache[n][r] = bino2(n - 1, r - 1) + bino2(n - 1, r);//直接计算并保存到数组
}

int main()
{
	int n, r;
	int i, j;
	for (i = 0; i < MAX; i++){
		for (j = 0; j < MAX; j++)
			cache[i][j] = -1;  //初始化为-1
	}
	cout << "请输入二项式系数n,r" << endl;
	cin >> n >> r;
	bino2(n, r);//利用制表计算二项式系数

	cout << bino2(n, r) << endl;
	system("pause");
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值