数字三角形2

题目一个数字三角宝塔。

设数字三角形中的数字为绝对值不超过1000的整数

现规定从最顶层走到最底层,每一步可沿向下或向右下走。

求解从最顶层走到最底层的一条路径,使得沿着该路径所经过的数字的总和的绝对值最大,输出最大值。

Input

输入数据的第1 行是数字三角形的行数n,1<=n<=1000。

接下来n行是数字三角形各行中的数字。所有数字都小于1000。

Output

程序运行结束时,将计算出的最大值输出。

输入数据 1

4
1
3 2
4 10 1
4 3 2 20 

输出数据 1

24

思路:

    这类题目其实有两种方式:一种是考虑路径从上到下,另外一种是考虑路径从下到上,因为元素的值是不变的,所以路径的方向不同也不会影响最后求得的路径和。如果是从上到下,你会发现,在考虑下面元素的时候,起始元素的路径只会从[i - 1][j] 获得,且每行当中的最后一个元素的路径只会从 [i - 1][j - 1] 获得,中间二者都可,这样就需要处理边界问题,而且到了最后还需要判断最后一行各数的绝对值大小,比较麻烦。因此这里考虑从下到上的方式,状态的定义就变成了 “最后一行元素到当前元素的最大或最小路径和”,对于 [1][1] 这个元素来说,最后状态表示的就是我们的最终答案。  

    另外,由于题意要求总和的绝对值最大,所以我们需要用2个DP数组来分别计算最大值和最小值的情况,最后判断两个数组中dp[1][1]的绝对值大小就行。

AC代码:

#include<bits/stdc++.h>
using namespace std;

int nums[1001][1001], dpMax[1001][1001], dpMin[1001][1001];
int main() {   
	int n;
	cin >> n;
	for (int i = 1; i <= n; ++i)
		for (int j = 1; j <= i; ++j)
			cin >> nums[i][j];
	for (int i = 1; i <= n; ++i) { //最后一行赋值给两个DP数组
		dpMax[n][i] = nums[n][i];
		dpMin[n][i] = nums[n][i];
	}
	for (int i = n - 1; i >= 1; --i)
		for (int j = 1; j <= i; j++) {
			//当前最大值为下层两个数最大值与当前数的和
			dpMax[i][j] = max(dpMax[i + 1][j], dpMax[i + 1][j + 1]) + nums[i][j];
			//当前最小值为下层两个数最小值与当前数的和
			dpMin[i][j] = min(dpMin[i + 1][j], dpMin[i + 1][j + 1]) + nums[i][j];
		}
	//输出绝对值最大值
	cout << (abs(dpMax[1][1]) > abs(dpMin[1][1]) ? abs(dpMax[1][1]) : abs(dpMin[1][1]));
	return 0;
}

  • 11
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值