考慮對每一列進行 DP。
記 $f(i,j)$ 代表從 $(1,1)$ 走到第 $i$ 列第 $j$ 行的最大值,$sum(i,j,k)$ 代表在第 $i$ 列中第 $j$ 行到第 $k$ 行的數字之和。
那么很明顯地,當 $i>1$ 時 $f(i,j)$ 一定收到 $f(i-1,k)$ 中的其中一個 $k$ 推導出。
而從 $f(i-1,k)$ 走到 $f(i,j)$,就需要這樣走:$(i-1,k)\rightarrow (i,k) \rightarrow (i,j)$。
如果不這么走,變為 $(i-1,k)\rightarrow (i-1,j) \rightarrow (i,j)$ 路徑的話,那你也沒必要從 $(i-1,k)$ 出發求得答案,直接往右移動一格即可。
所以,轉移方程為:
$$f(i,j)=\max\{f(i-1,k)+sum(i,\min(j,k),\max(j,k))\}+a_{i,j}$$
處理一下各列前綴和,時間復雜度 $O(n^2m)$,可以拿到 70 分。
現在考慮如何優化:
可以觀察到,$(i-1,k)\rightarrow (i,k)$ 后,想到達任意一個 $(i,j)$ 只能往上或往下走。
這說明一些 $f(i,j)$ 可能與 $f(i,j-1)$ 或 $f(i,j+1)$ 的答案路徑有重合部分,即 $f(i,j-1)$ 或 $f(i,j+1)$ 可能推出 $f(i,j)$。
但 DP 不能有后效性,不能在同一列又上又下,所以我們開兩個數組 $g,h$,並設計策略:
$$g(i,j)=\max(f(i-1,j),g(i,j-1))+a_{i,j}$$
$$h(i,j)=\max(f(i-1,j),h(i,j+1))+a_{i,j}$$
$$f(i,j)=\max(g(i,j),h(i,j))$$
特殊地,對於 $i>1$,$g(i,1)=f(i-1,1)+a_{i,1}$,$h(i,n)=f(i-1,n)+a_{i,n}$。
正確性顯然,對於任意 $(i,j)$, $g$ 和 $h$ 至少包含一條答案最大路徑。
時間復雜度 $O(nm)$,$g,h$ 數組可以降至一維重復使用。
注意開 long long。