题意:

给你一个倒三角形,计算从顶部开始到底部某个地方的路径中所有数字总和的最大值,每次只能向左斜向下或者右斜向下走

思路:

使出秘技dp

根据雨巨的说法,有两种,我从哪里来?我到哪里去?

对于我从哪里来,写状态方程的话是这样的:

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

但是这样有i - 1,如果出现负数的的话就不好处理,所以我们可以写我到哪里去

对于第tr[i] [j]的数来说,他对tr[i - 1] [j] 和 tr[i - 1] [ j - 1] 有贡献

也就是说

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

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

这样的话就不需要考虑出界问题,very good!

#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <stdlib.h>
#include <sstream>
#include <map>
#include <set>
using  namespace std;
#define inf 0x3f3f3f3f
#define MAX 1000000 + 7
#define endl '\n'
//#define mod 571373;
typedef  long long ll ;
//不开longlong见祖宗!
//ios::sync_with_stdio(false);
//cin.tie(0); cout.tie(0);
inline int IntRead(){char ch = getchar();int s = 0, w = 1;while(ch < '0' || ch > '9'){if(ch == '-') w = -1;
        ch = getchar();}while(ch >= '0' && ch <= '9'){s = s * 10 + ch - '0';ch = getchar();}return s * w;}

ll n, m, x, y;
ll dp[105][105], tr[105][105];

int main(){
    cin>>n;
    for(int i = 1; i <= n ;++i){
        for(int j = 1; j <= i; ++j){
            cin>>tr[i][j];
        }
    }
    memset(dp, -1, sizeof(dp));
    dp[1][1] = tr[1][1];
    for(int i = 1; i < n;++i){
        for(int j = 1; j <= i; ++j){
            dp[i + 1][j] = max(dp[i][j] + tr[i + 1][j], dp[i + 1][j]);
            dp[i + 1][j + 1] = max(dp[i + 1][j + 1],tr[i + 1][j + 1] + dp[i][j]);
        }
    }
    ll maxn = -1;
    for(int i = 1; i <= n; ++i){
        maxn = max(maxn, dp[n][i]);
    }
    cout<<maxn<<endl;
}