递推

25 篇文章 1 订阅
10 篇文章 0 订阅

如果要求出 dp[i][j],那么一定要先求出它的两个子问题:
①从位置(i+1,  j) 到达最底层的最大和 dp[i+1][j];
②从位置(i+1, j+1) 到达最底层的最大和 dp[i+1][j+1]。

状态转移方程

dp[i][j] = max(dp[i+1][j], dp[i+1][j+1]) +f[i][j]

把状态 dp[i][j] 转移为 dp[i+1][j] 和 dp[i+1][j+1]

边界:最后一层的dp值总是等于元素本身。

dp[n][j] = f[n][j] (i \leq j\leq n)

 从这些边界出发,通过状态转移方程扩散到整个 dp数组。

数塔问题 

// 03.16 10:00-12:00

#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 1000;

int f[maxn][maxn], dp[maxn][maxn];

int main() {
	freopen("input.txt", "r", stdin);
	// 输入数塔
	int n;
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= i; j++) {
			scanf("%d", &f[i][j]);
		}
	}
	// 边界
	for (int j = 1; j <= n; j++) {
		dp[n][j] = f[n][j];
	}
	// 从倒数第二层(n-1)层,往上计算 dp[i][j]
	for (int i = n - 1; i >= 1; i--) {
		for (int j = 1; j <= i; j++) {
			dp[i][j] = max(dp[i + 1][j], dp[i + 1][j + 1]) + f[i][j];
		}
	}
	printf("%d\n", dp[1][1]);
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值