原題
Hello Kitty想摘點花生送給她喜歡的米老鼠,
她來到一片有網格狀道路的矩形花生地(如下圖),從西北角進去,東南角出來,
地里每個道路的交叉點上都有種著一株花生苗,上面有若干顆花生,經過一株花生苗就能摘走該它上面所有的花生,
Hello Kitty只能向東或向南走,不能向西或向北走,
問Hello Kitty最多能夠摘到多少顆花生,

輸入格式
第一行是一個整數T,代表一共有多少組資料,
接下來是T組資料,
每組資料的第一行是兩個整數,分別代表花生苗的行數R和列數 C,
每組資料的接下來R行資料,從北向南依次描述每行花生苗的情況,每行資料有C個整數,按從西向東的順序描述了該行每株花生苗上的花生數目M,
輸出格式
對每組輸入資料,輸出一行,內容為Hello Kitty能摘到得最多的花生顆數,
資料范圍
\(1\leq T \leq 100,\)
\(1\leq R,C \leq 100,\)
\(0\leq M \leq 1000\)
輸入樣例:
2
2 2
1 1
3 4
2 3
2 3 4
1 6 5
輸出樣例:
8
16
解題思路
- 狀態表示:
f(i, j):從(1,1)→(i,j)的所有方案中摘得花生最多的數量 - 狀態轉移:
\((i-1,j)\rightarrow (i,j)\)
\((i,j-1)\rightarrow (i,j)\)
代碼實作
樸素版
#include <iostream>
using namespace std;
const int N = 105;
int w[N][N], f[N][N];
int main() {
int t;
cin >> t;
while (t --) {
int r, c;
cin >> r >> c;
for (int i = 1;i <= r; i ++) {
for (int j = 1; j <= c; j ++) {
cin >> w[i][j];
}
}
for (int i = 1; i <= r; i ++) {
for (int j = 1; j <= c; j ++) {
f[i][j] = max(f[i-1][j], f[i][j-1])+w[i][j];
}
}
cout << f[r][c] << endl;
}
return 0;
}
時間復雜度:\(O(2n^2)\)
空間復雜度:\(O(2n^2)\)
優化版
#include <iostream>
using namespace std;
const int N = 105;
int f[N][N];
int main() {
int n;
cin >> n;
for (int k = 0; k < n; k ++) {
int r, c;
cin >> r >> c;
// 輸入與計算合并
for (int i = 1; i <= r; i ++) {
for (int j = 1; j <= c; j ++) {
int v;
cin >> v;
f[i][j] = max(f[i - 1][j], f[i][j - 1]) + v;
}
}
cout << f[r][c] << endl;
}
return 0;
}
時間復雜度:\(O(n^2)\)
空間復雜度:\(O(n^2)\)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/502842.html
標籤:其他
