【hiho一下】第五周 数字三角形

题目1:数字三角形

题目原文:http://hihocoder.com/contest/hiho5/problem/1

【题目解读】

最基础的动态规划,提示中对于可以使用动态规划的基本条件说明,感觉非常好:

(1)无后效性:“无论我是通过怎么样的方式到达第i层第j个房间的,我之前做出的选择不会对我之后的选择做出限制与优待。就像如果我规定至少要向右走3次,那么状态就不仅仅是(i, j, k)这样,还要加上一个已经向右走的次数,那么你觉得还能就直接像我们之前的方法进行计算么?如果到达第i层第j个房间的路上向右走过3次了,那么之后的走法就没有任何限制,不然就仍会有一个至少要向右走一定次数的限制。”

(2)重复子问题:“我们将从起点出发到走出迷宫的最优路分解成了两个子问题,其一是从第2层的第1个房间走出迷宫的最优路,其二是从第2层的第2个房间走出迷宫的最优路,只要能算出这两个部分的最优值,我就可以知道从起点出发到走出迷宫的最优路。”小Hi道:”而按照这样的方法,这两个子问题都有一个相同的子问题——从第3层的第2个房间出发走出迷宫的最优路。””

【编写细节】

DP最难的是边界处理部分,一般都是

(1)best[0][0] 单独处理,n=1 时单独处理;

(2)本题中,三角形最左侧一列、最右侧一斜列,需要单独处理。

【AC代码】

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int reward[101][101];
long best[101][101];

long max(long a, long b)
{
	if(a>b) return a;
	else return b;
}

int main()
{
	int n;
	scanf("%d", &n);
	memset(reward, 0, sizeof(reward));
	memset(best, 0, sizeof(best));
	
	for(int i=0; i<n; i++)
		for(int j=0; j<=i; j++)
			scanf("%d", &reward[i][j]);
			
	best[0][0] = reward[0][0];
	for(int i=1; i<n; i++)
		for(int j=0; j<=i; j++)
		{
			if(j-1 < 0)
			{
				best[i][j] = best[i-1][j] + reward[i][j];
			}
			else if(i==j)
			{
				best[i][j] = best[i-1][j-1] + reward[i][j];
			}
			else
			{
				best[i][j] = max(best[i-1][j-1], best[i-1][j]) + reward[i][j];
			}
		}
	
	long ans = best[n-1][0];
	for(int k=0; k<n; k++)
	{
		ans = max(best[n-1][k], ans);
	}
	printf("%ld\n", ans);
	return 0;
}


你可能感兴趣的:(dp,动态规划,OJ,hiho)