动态规划(待完善)

动态规划

1.子段和问题

问题描述:

给出一段长度为n的整数序列,选出其中连续且非空的一段使得这段和最大。

例如序列:

2 -4 3 -1 2 -4 3

3 -1 2 -4 3 的和是3

3 -1 2的和是4,是子段和中最大的

code:

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n, a[200005], dp[200005], maxx = -1e9;
signed main() {
	cin >> n;
	for(int i = 1;i <= n;i ++) {
		cin >> a[i];
	}
	dp[n] = a[n];
	maxx = max(maxx, a[n]);
	for(int i = n - 1;i >= 1;i --) {
		dp[i] = max(a[i] + dp[i + 1], a[i]);
		maxx = max(maxx, dp[i]);
	}
	cout << maxx;
	return 0;
}

2. 数字三角形问题

下图所示为一个数字三角形,其中三角形中的数值为整数,现规定从最顶层往下走到底层,每一步可沿左斜线向下或右斜线向下走。

        7
      3   8
    8   1   0
  2   7   7   4

要求计算从最顶层走到最底层的一条路径,使得沿着该路径所经过的数字之和最大。

上图给出了n=4时的一个数字三角形。

数据存储与表示:

可以转化为上面的结构用二维数组来存储,数字三角形上的每一个数字对应一个行列号 \(i\)\(j\)

不难发现,本问题具有

“最优子结构性质”

假设(r,c)为起点的一条最优路线表示为 R(r,c) = (r,c) (r2,c2) (r3,c3)… 最优解表示为 F(r,c)

则当 r < n 时,R(r,c)F(r,c) 一定是下面两种情况中的一种:

  1. R(r, c) = (r, c) R(r + 1, c) F(r, c) = F(r + 1, c) + a[r][c]
  2. R(r, c) = (r, c) R(r + 1, c + 1) F(r,c) = F(r + 1, c + 1) + a[r][c]

拆、求、和

核心:找到原问题与子问题的关系

核心代码:

for(int j = 1;j <= n;j ++) {
	f[n][j] = a[n][j];
}
for(int i = n - 1;i >= 1;i --) {
	for(int j = 1;j <= i;j ++) {
		f[i][j] = max(f[i + 1][j], f[i + 1][j + 1]) + a[i][j];
	}
}
posted @ 2025-04-20 19:41  CuteFurina  阅读(7)  评论(0)    收藏  举报