动态规划的进一步理解

动态规划为了求取全局最优解,重新建立一个 dp 数组,用来存储当前最优值,直到达到全局最优值为止。

例如:一块N*M的矩形土地被分成N*M个小块,每一小块有不同数量的硬币,如果我从这块土地的左上角出发,到达右下角时,能拾到最多硬币是多少。(只能往前走或往下走,不能往上或回头走);

如果我们用贪心算法,就是看一下前方和下放,哪一块硬币最多,就往哪块走。如果这样走肯定会误导我们,就可能会错过得到最大硬币数量的方案;

如何才能做到每一步走的都是最优的,想做到这一点肯定是要用到动态规划求得最优解;换种说法就是说,我们可以把原来的小矩形状态换为当前状况的最优解,从而可以求得到达任意一个小方块的最优解;

到达任意一个小方块的最优解都已经找到了,结果就很自然出来了!

计算到达某个小方块最优解时,要找到这个解来源于什么地方,找到控制这个解的条件有哪些 。(找到条件)

输入
第一行:N M (1≤N M≤20 0≤Xij≤500(i=1,2„.N, j=1,2„,M)
)表示沙漠是一个N*M的矩形区域
接下来有N行:每行有M个正整数,Xi1 Xi2 ……Xim 表示各位置中的虫子数(单个空格隔开)
假设“KK”只能向右走或向下走。
输出
输出有一个整数, 表示“KK”吃掉最多的虫子数。
样例输入
3 4
3 1 2 8
5 3 4 6
1 0 2 3
样例输出
24

#include<iostream>
#include<string.h>
using namespace std ;
int main()	{
	int a[25][25] , dp[25][25] = {0} ;
	int i , j ;
	int n , m ;
	cin >> n >> m ;
	for(i = 1 ; i <= n ; i++)
		for(j = 1 ; j <= m ; j++)
			cin >> a[i][j] ;
	i = 1 ;
	for(j = 1 ; j <= m ; j++)
		dp[i][j] = dp[i][j-1] + a[i][j] ;
	j = 1 ;
	for(i = 1 ; i <= n ; i++)
		dp[i][j] = dp[i-1][j] + a[i][j] ;
	for(i = 2 ; i <= n ; i++)
		for(j = 2 ; j <= m ; j++)
			if(dp[i-1][j] < dp[i][j-1])
				dp[i][j] = dp[i][j-1] + a[i][j] ;
			else
				dp[i][j] = dp[i-1][j] + a[i][j] ;
	cout << dp[n][m] << endl ;
	return 0 ;
}

  

原文地址:https://www.cnblogs.com/NYNU-ACM/p/4237417.html