动态规划学习日记(三)

**例4:**数字三角形问题:给定一个有n行数字组成的数字三角形. 试设计一个算法, 计算出从三角形的顶至底的一条路径, 使该路径经过的数字和最大.(例题)

7
38
810
2744
45265

一、确定状态:

终点:(n-1,i)前一个点(n - 2, i - 1)或(n - 2 ,i)

子问题:转化为到前一步有可能的两个点的和。设f[i] [j]为最大和。

二、确定转移方程:

f[i] [j] = max{f[i-1] [j-1] + a[i-1] [j-1],f[i-1] [j] + a[i-1] [j]}

三、确定初始条件和边界情况:

初始条件:f[0] [0] = a[0] [0];

边界情况:f[i] [0] = f[i-1] [0] + a[i-1] [0]

四、确定计算顺序:

从上至下

代码:

#include <iostream>
#include <cstring>
using namespace std;
int a[105][105];
int f[105][105];
void Init(){
	memset(a, 0 ,sizeof(a));
	memset(f, 0 ,sizeof(f));	
}
int Max(int x, int y){
	if(x >= y)
		return x;
	else
		return y;
}
void F(int n){
	f[0][0] = 0;
	int i, j;
	for(i = 0; i < n; i++)
	{
		for(j = 0; j <= i; j++)
		{
			if(!i && !j)
			{
				f[i][j] = a[i][j];
				break;
			}
			if(i == j)
			{
				f[i][j] = f[i-1][j-1] + a[i][j]; 
			}
			else if(!j)
				{
					f[i][j] = f[i-1][j] + a[i][j];
				}
				else
				{
					f[i][j] = Max((f[i-1][j] + a[i][j]), (f[i-1][j-1] + a[i][j]));
				}		
		}	

	}
}
int main(int argc, char** argv) {
	Init();
	int n;
	cin>>n;
	int i, j;
	for(i = 0; i < n; i++)
	{
		for(j = 0; j <= i; j++)
			cin>>a[i][j];
	}
	F(n);
	int m = 0;
	for(i = 0; i < n; i++)
	{
		if(f[n-1][i] > m)
			m = f[n-1][i];
	}
	
	cout<<m<<endl;
	return 0;
}

**总结:**这个题属于之前的最大(小)值类的问题,是学校oj上的一道作业题,思路比较简单,另外从下到上也可以,唯一困难的地方可能是在于题意的理解,从上一个点出发只能往右下或者正下方移动而不能往左下方移动,这点花了我很长时间,所幸得大佬指点(笑)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值