深搜, 复杂度O(2^n), 不能ac
#include<bits/stdc++.h>
using namespace std;
const int N = 1e4 + 10;
int a[N][N];
int ans = 0, n;
void dfs(int x, int y, int cnt) {
if (x == n - 1) {
if (cnt > ans) ans = cnt;
return;
}
dfs(x + 1, y, cnt + a[x + 1][y]);
dfs(x + 1, y + 1, cnt + a[x + 1][y + 1]);
}
int main()
{
cin>>n;
for(int i = 0; i < n; i++) {
for(int j = 0; j <= i; j++) {
cin>>a[i][j];
}
}
dfs(0, 0, a[0][0]);
cout<<ans;
return 0;
}
记忆化搜索, 复杂度O(n^2)
#include<bits/stdc++.h>
using namespace std;
const int N = 1e4 + 10;
int a[N][N];
int f[N][N]; // 记录从下向上的累加和
int ans = 0, n;
int dfs(int x, int y) {
if (f[x][y] != 0) return f[x][y];
if (x == n - 1) f[x][y] = a[x][y];
else f[x][y] = a[x][y] + max(dfs(x + 1, y), dfs(x + 1, y + 1));
return f[x][y];
}
int main()
{
cin>>n;
for(int i = 0; i < n; i++) {
for(int j = 0; j <= i; j++) {
cin>>a[i][j];
}
}
dfs(0, 0);
cout<<f[0][0];
return 0;
}
动态规划(线性dp, 顺推) 复杂度O(n^2)
#include<bits/stdc++.h>
using namespace std;
const int N = 1e4 + 10;
int a[N][N];
int f[N][N];
int n;
const int INF = 0x3f3f3f3f;
int main()
{
cin>>n;
for (int i = 0; i <= n + 1; i++) {
memset(f[i], -INF, sizeof(f[i]));
}
for (int i = 1; i <= n; i++) { // 注意读取的下标 和之前不一样
for (int j = 1; j <= i; j++) {
cin>>a[i][j];
}
}
f[1][1] = a[1][1];
for (int i = 2; i <= n; i++) {
for (int j = 1; j <= i; j++) {
f[i][j] = max(f[i - 1][j - 1], f[i - 1][j]) + a[i][j];
}
}
int ans = - INF;
for (int i = 1; i <= n; i++) ans = max(f[n][i], ans);
cout<<ans;
return 0;
}
动态规划(线性dp, 逆推) 复杂度O(n^2)
#include<bits/stdc++.h>
using namespace std;
const int N = 1e4 + 10;
int f[N][N];
int n,a[N][N];
int main() {
cin>>n;
for(int i=1; i<=n; i++)
for(int j=1; j<=i; j++)
cin>>a[i][j];
for(int i=n; i>=1; i--)
for(int j=i; j>=1; j--)
f[i][j] += max(f[i+1][j] , f[i+1][j+1]) + a[i][j];
cout<<f[1][1];
return 0;
}