目录
DFS+记忆化
代码:
//【例9.2】数字金字塔
#include <iostream>
#include <cstring>
using namespace std;
const int N = 1005;
int a[N][N], dp[N][N];
int n, ans;
int dfs(int x, int y) {
if (dp[x][y] != -1) return dp[x][y];
if (x == n - 1)
return dp[x][y] = a[x][y];
return dp[x][y] = max(dfs(x+1, y), dfs(x+1, y+1)) + a[x][y];
}
int main() {
scanf ("%d", &n);
for (int i = 0; i < n; i ++)
for (int j = 0; j <= i; j ++)
scanf ("%d", &a[i][j]);
// dfs(0, 0, 0);
//
// cout << ans;
memset(dp, -1, sizeof dp);
cout << dfs(0, 0);
return 0;
}
/*
输入样例:
5
13
11 8
12 7 26
6 14 15 8
12 7 13 24 11
输出样例:
86
*/
动态规划
这里用两种方法,自顶向下写法(dp1)和自底向上写法(dp2)
代码:
//【例9.2】数字金字塔
#include <iostream>
#include <cstring>
using namespace std;
const int N = 1005;
int a[N][N], dp[N][N];
int n, ans;
int dp1() {
/*
自顶向下写法
状态设计
dp[i][j] = 从(1, 1)到(i, j)的MAX
状态转移
dp[i][j] = max(dp[i-1][j], dp[i-1][j-1]) + a[i][j];
初始化
dp[1][1] = a[1][1];
输出
max(dp[n][1] ~ dp[n][n])
*/
dp[1][1] = a[1][1];
for (int i = 2; i <= n; i ++)
for (int j = 1; j <= i; j ++)
dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - 1]) + a[i][j];
int res = 0;
for (int i = 1; i <= n; i ++)
res = max(res, dp[n][i]);
return res;
}
int dp2() {
/*
自底向上写法
状态设计
dp[i][j] = 从底部到(i, j)的MAX
状态转移
dp[i][j] = max(dp[i+1][j], dp[i+1][j+1]) + a[i][j];
初始化
for (i : 1 -> n) dp[n][i] = a[n][i];
输出
dp[1][1]
*/
for (int i = 1; i <= n; i ++)
dp[n][i] = a[n][i];
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]) + a[i][j];
return dp[1][1];
}
int main() {
scanf ("%d", &n);
for (int i = 1; i <= n; i ++)
for (int j = 1; j <= i; j ++)
scanf ("%d", &a[i][j]);
cout << dp1();
// cout << dp2();
return 0;
}
/*
输入样例:
5
13
11 8
12 7 26
6 14 15 8
12 7 13 24 11
输出样例:
86
*/
原题链接:信息学奥赛一本通(C++版)在线评测系统 (ssoier.cn)
请勿转载, 创作不易,留个赞再走吧!(●'◡'●)