AcWing 1027. 方格取數(線性DP)
阿新 • • 發佈:2022-04-10
題目描述
設有 N×N 的方格圖,我們在其中的某些方格中填入正整數,而其它的方格中則放入數字0。如下圖所示:
某人從圖中的左上角 A 出發,可以向下行走,也可以向右行走,直到到達右下角的 B 點。
在走過的路上,他可以取走方格中的數(取走後的方格中將變為數字0)。
此人從 A 點到 B 點共走了兩次,試找出兩條這樣的路徑,使得取得的數字和為最大。
題目模型
- 集合表示:f(k,i1,i2)
- 集合含義:所有從分別(1,1)走到(i1,k-i1)和(i2,k-i2)的路線,k表示橫縱座標的和
- 集合屬性:max
- 集合劃分:
題目程式碼
#include <iostream> #include <cstring> #include <algorithm> using namespace std; const int N = 15; int n; int w[N][N]; int f[N * 2][N][N]; int main() { scanf("%d", &n); int a, b, c; while(cin >> a >> b >> c, a || b || c ) w[a][b] = c; //特殊的讀入方式 for(int k = 2; k <= n + n; k ++ ) for(int i1 = 1; i1 <= n; i1 ++ ) for(int i2 = 1; i2 <= n; i2 ++ ) { int j1 = k - i1, j2 = k - i2; if(j1 >= 1 && j1 <= n && j2 >= 1 && j2 <= n) //注意判斷 { int t = w[i1][j1]; if(i1 != i2) t += w[i2][j2]; int &x = f[k][i1][i2]; x = max(x, f[k - 1][i1 - 1][i2 - 1] + t); x = max(x, f[k - 1][i1 - 1][i2] + t); x = max(x, f[k - 1][i1][i2 - 1] + t); x = max(x, f[k - 1][i1][i2] + t); } } printf("%d\n", f[n + n][n][n]); return 0; }