题意:
给你一个倒三角形,计算从顶部开始到底部某个地方的路径中所有数字总和的最大值,每次只能向左斜向下或者右斜向下走
思路:
使出秘技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; }