在一個 n \times mn×m 中的方格中,每一個格子上都有一個分數,如今蒜頭君從 (1,1)(1,1) 的格子開始往 (n, m)(n,m) 的格子走。要求從 (x_1,y_1)(x1,y1) 到 (x_2,y_2)(x2,y2) ,知足 x_2 \ge x_1,\ y_2 \ge y_1x2≥x1, y2≥y1 。請問蒜頭君從 (1,1)(1,1) 的點到 (n,m)(n,m) 最多能夠得多少分?html
每一個格子的分數只能獲得一次,其中 (1,1)(1,1) 和 (n,m)(n,m) 是必需要走的兩個格子,(1,1)(1,1) 表示第一行第一列的方格。ios
第一行輸入兩個整數 n,mn,m ,表示有 n\times mn×m 個方格。ide
接下來輸入 nn 行 mm 列個整數 gradegrade 。ui
對於 100\%100% 的數據,-300 \le grade \le 300−300≤grade≤300。spa
對於 30\%30% 的數據, 1 \le n,m \le 51≤n,m≤5 。debug
對於 60\%60% 的數據, 1 \le n,m \le 601≤n,m≤60 。htm
對於 100\%100% 的數據, 1 \le n,m \le 5001≤n,m≤500blog
輸出一個整數表示蒜頭君能獲取到的最大分數。ip
3 3 1 2 3 4 5 6 7 8 9
29
題解:
很容易的想到dp表達式 dp[i][j] = max(dp[i-1][j], dp[i][j-1]) + a[i][j]
可是這題目的意思是每一個格子的分數可要可不要,(1,1),(n,m)格子的分數必需要
因此在代碼中得加幾個判斷,除(1,1),(n,m)外的其餘小於0的分數都不要
#include <map> #include <set> #include <stack> #include <cmath> #include <queue> #include <cstdio> #include <vector> #include <string> #include <bitset> #include <cstring> #include <iomanip> #include <iostream> #include <algorithm> #define ls (r<<1) #define rs (r<<1|1) #define debug(a) cout << #a << " " << a << endl using namespace std; typedef long long ll; const ll maxn = 1e3+10; const ll mod = 1e9+7; const double pi = acos(-1.0); const double eps = 1e-8; ll n, m, a[maxn][maxn], dp[maxn][maxn]; int main() { scanf("%lld%lld",&n,&m); for( ll i = 1; i <= n; i ++ ) { for( ll j = 1; j <= m; j ++ ) { scanf("%lld",&a[i][j]); } } for( ll i = 1; i <= n; i ++ ) { for( ll j = 1; j <= m; j ++ ) { if( ( i == 1 && j == 1 ) || ( i == n && j == m ) ) { dp[i][j] = a[i][j] + max(dp[i-1][j],dp[i][j-1]); } else { dp[i][j] = max((ll)0,a[i][j]) + max(dp[i-1][j],dp[i][j-1]); } } } cout << dp[n][m] << endl; return 0; }