二维动态规划(收集苹果)

平面上有N*M个格子,每个格子中放着一定数量的苹果。你从左上角的格子开始,每一步只能向下走或是向右走,每次走到一个格子上就把格子里的苹果收集起来,这样下去,你最多能收集到多少个苹果
解这个问题与解其它的DP问题几乎没有什么两样。第一步找到问题的“状态”,第二步找到“状态转移方程”,然后基本上问题就解决了。首先,要找到这个问题中的“状态”是什么?必须注意到的一点是,到达一个格子的方式最多只有两种:从左边来的(除了第一列)和从上边来的(除了第一行)。因此为了求出到达当前格子后最多能收集到多少个苹果,就要先去考察那些能到达当前这个格子的格子,到达它们最多能收集到多少个苹果。 (是不是有点绕,但这句话的本质其实是DP的关键:欲求问题的解,先要去求子问题的解)
经过上面的分析,可以得出问题的状态和状态转移方程。状态S[i][j]表示走到(i, j)这个格子时,最多能收集到多少个苹果。那么,状态转移方程如下:
S[i][j]=A[i][j] + max(S[i-1][j] if i>0 ; S[i][j-1], if j>0)
其中i代表行,j代表列,下标均从0开始;A[i][j]代表格子(i, j)处的苹果数量。
S[i][j]有两种计算方式:
1.对于每一行,从左向右计算,然后从上到下逐行处理;
2. 对于每一列,从上到下计算,然后从左向右逐列处理。这样做的目的是为了在计算S[i][j]时,S[i-1][j]和S[i][j-1]都已经计算出来了。

#include <iostream>
using namespace std;
#define MAX_N 100
#define MAX_M 100
int arr[ MAX_N ][ MAX_M ] = { 0 };
int dp[ MAX_N + 2 ][ MAX_M + 2 ] = { 0 }; 
int main(){
	int n, m;
	cin>> n >> m;  //输入n*m的方格
	int i, j ;
	for( i = 0; i < n; i++){
		for( j = 0; j < m; j++)
			cin>> arr[ i ][ j ];
	} //输入方格中各个格子中的苹果数量
	for( i = 0; i < n; i++){
		for( j = 0; j < m; j++){
			dp[ i + 1 ][ j + 1 ] = dp[ i ][ j + 1] > dp[ i + 1 ][ j ] ? 
						dp[ i ][ j + 1] + arr[ i ][ j ] : dp[ i + 1][ j ] + arr[ i ][ j ]; //动态规划最重要的状态转移方程
		}
	} 
	cout<<dp[i][j]<<endl;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值