[Hnoi 2007] Magical amusement Park
#include <bits/stdc++.h> #define MAXN 110using namespace Std;typedef long Long ll;int N, m;int a[maxn][maxn];ll ans = -1LL << #define M 2000010#define mod 997struct hashmap{ll st[m];int h[1000], size, nxt[m];ll f[m];void clear () {m Emset (h, 0, sizeof h); size = 0;} void push (LL Hash_, ll val) {int tmp = hash_% mod;for (int i = h[tmp]; i; i = Nxt[i]) {if (st[i] = = Hash_) {F[i] = max (F[i], V (al); return;}} int now = + + Size;f[now] = Val;st[now] = Hash_;nxt[now] = h[tmp];h[tmp] = Now;}} Dp[2];int cur, code[20], ch[20];void Decode (ll St) {for (int i = m; I >= 0; i--) code[i] = st & 7, St >>= 3 ;} ll Encode () {LL ret = 0;memset (CH,-1, sizeof CH); ch[0] = 0; int cnt = 0;for (int i = 0; I <= m; i + +) {if (ch[code[i]] = = -1) Ch[code[i] = + + Cnt;code[i] = Ch[code[i]];ret = ret << 3 | Code[i];} return ret;} void Shift () {for (int i = m; I >= 1; i-) code[i] = code[i-1];code[0] = 0;} inline void Change (int u, int. v) {for (int i = 0; I <= m; i + +) if (code[i] = = v) Code[i] = u;} void DP (int i, int j) {dp[cur^1].clear (); for (int k = 1; k <= dp[cur].size; k + +) {Decode (dp[cur].st[k]); if (j = = 1) {if E[M]) continue; Shift ();} int left = Code[j-1], up = Code[j];if (left && up) {code[j] = code[j-1] = 0;if (left = = up) {ll ENCODE = Encode (); if (Encode = = 0) ans = max (ans, dp[cur].f[k] + a[i][j]);} else{change (left, up); Dp[cur^1].push (Encode (), dp[cur].f[k] + a[i][j]);}} else if (left | | UP) {int tmp = left? Left:up;code[j-1] = 0, code[j] = Tmp;dp[cur^1].push (Encode (), dp[cur].f[k] + a[i][j]); Code[j] = 0, code[j-1] = Tmp;dp[cu R^1].push (Encode (), dp[cur].f[k] + a[i][j]);} else{Dp[cur^1].push (Encode (), dp[cur].f[k]); CODE[J] = code[j-1] = 8; Dp[cur^1].push (Encode (), dp[cur].f[k] + a[i][j]);}} Cur ^= 1;} int main () {#ifndef Online_judge freopen ("park.in", "R", stdin); Freopen ("Park.out", "w", stdout), #endifscanf ("%d%d", &n, &m); for (int i = 1; I <= n; i + +) for (int j =1; J <= M; J + +) scanf ("%d", &a[i][j]);DP [Cur].clear ();DP [Cur].push (0, 0); for (int i = 1; I <= n; i + +) for (int j = 1; j <= m; J + +) DP (i, J);p rintf ("%lld\n", ans); return 0;}
Glued a template up =-=
Based on the dynamic programming of connectivity, the minimal notation is very useful.
We can use a compressed number to indicate a connectivity situation, such as record spanning tree, record probability, record the lattice on the board, etc.
As long as connectivity and n hours can be used qaq.
Forgot the template again Qaq
That is, if the left and the top is a connected component, that is, leave = = up, we want to merge the connected components, so at this point there has been a circle, this problem can not have multiple loops, so the final not put in
CODE[J] = code[j-1] = 0.
[Plug DP]