传送门:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1187
巨裸的插头dp,没什么好说的。
代码巨丑TAT...
#include <iostream> #include <cstdio> #include <cstring> using namespace std; #define INF 0x3f3f3f3f const int maxn = 1100; const int maxm = 80; const int Hash = 1007; const int maxk = 10010; struct node { int fir[Hash], edge[maxk], next[maxk], f[maxk], ss[maxk]; int cnt; void cr() { memset(fir, -1, sizeof(fir)); cnt = 0; } void push(int s, int v) { for(int i = fir[s % Hash]; ~i ; i = next[i]) { int p = edge[i]; if(p == s) { f[i] = max(f[i], v); return; } } edge[cnt] = s; next[cnt] = fir[s % Hash]; fir[s % Hash] = cnt; f[cnt] = v; ss[cnt ++] = s; return; } }d[2]; int n, m, ans = -INF; int a[maxn][maxm]; int find_pos(int s, int p) { return (s >> (p << 1)) & 3; } void tp(int &s, int p, int v) { s &= (~(3 << (p << 1))); s |= (v << (p << 1)); return; } int find_r(int s, int p) { int cnt = 0; for(int i = p; i <= m; i ++) { if(find_pos(s, i) == 1) cnt ++; else if(find_pos(s, i) == 2) cnt --; if(!cnt) return i; } } int find_l(int s, int p) { int cnt = 0; for(int i = p; i >= 0; i --) { if(find_pos(s, i) == 2) cnt ++; else if(find_pos(s, i) == 1) cnt --; if(!cnt) return i; } } int main() { scanf("%d%d", &n, &m); for(int i = 1; i <= n; i ++) { for(int j = 1; j <= m; j ++) { scanf("%d", &a[i][j]); } } int cur = 0; d[cur].cr(); d[cur].push(0, 0); for(int i = 1; i <= n; i ++) { for(int j = 1; j <= m; j ++) { d[cur ^ 1].cr(); for(int k = 0; k < d[cur].cnt; k ++) { int t = d[cur].ss[k], tpos, tf = d[cur].f[k]; int l = find_pos(t, j - 1), r = find_pos(t, j); if(l && r) { if(l == 1 && r == 1) { tpos = find_r(t, j); tp(t, j - 1, 0); tp(t, j, 0); tp(t, tpos, 1); d[cur ^ 1].push(t, tf + a[i][j]); } else if(l == 2 && r == 1) { tp(t, j - 1, 0); tp(t, j, 0); d[cur ^ 1].push(t, tf + a[i][j]); } else if(l == 2 && r == 2) { tpos = find_l(t, j - 1); tp(t, j - 1, 0); tp(t, j, 0); tp(t, tpos, 2); d[cur ^ 1].push(t, tf + a[i][j]); } else { tp(t, j - 1, 0); tp(t, j, 0); if(!t) ans = max(ans, tf + a[i][j]); } } else if(l) { if(i < n) { d[cur ^ 1].push(t, tf + a[i][j]); } if(j < m) { tp(t, j - 1, 0); tp(t, j, l); d[cur ^ 1].push(t, tf + a[i][j]); } } else if(r) { if(j < m) { d[cur ^ 1].push(t, tf + a[i][j]); } if(i < n) { tp(t, j - 1, r); tp(t, j, 0); d[cur ^ 1].push(t, tf + a[i][j]); } } else { d[cur ^ 1].push(t, tf); if(i < n && j < m) { tp(t, j - 1, 1); tp(t, j, 2); d[cur ^ 1].push(t, tf + a[i][j]); } } } cur ^= 1; } for(int k = 0; k < d[cur].cnt; k ++) { d[cur].ss[k] <<= 2; } } printf("%d\n", ans); return 0; }