Http://codeforces.com/problemset/problem/111/C
An N * m chessboard. In the initial state, each grid has a spider. The spider can go up, down, and up or down in one step, or stop in the same place. Ask, how many vacancies can be generated at most by taking a step.
Considering that N * m is small, there is a one-dimensional <= 6. At this time, we should think that we can use state compression DP to solve this problem.
DP [I] [J] [k] indicates the first I row, and the status of row I is J, the maximum number of vacancies that can be generated when the status of row I + 1 is K (excluding row I + 1, therefore, it is much easier to determine whether certain statuses can be transferred, you only need to determine whether the middle row can be restored to the initial state (that is, whether the current state can be changed from the initial state)
Reference Code
#include <cstdio>#include <cstring>#include <set>#include <string>#include <iostream>#include <cmath>#include <vector>#include <map>#include <stack>#include <time.h>#include <queue>#include <cstdlib>#include <algorithm>using namespace std;#define lowbit(x) ((x)&(-(x)))#define sqr(x) ((x)*(x))#define PB push_back#define MP make_pair#define foreach(it, x) for(typeof(x.begin()) it = x.begin(); it!=x.end();it++)typedef unsigned long long ULL;typedef long long lld;typedef vector<int> VI;typedef vector<string> VS;typedef pair<int,int> PII;#define rep(i,n) for(int i=0;i<n;i++)#define For(i,a,b) for(int i=a;i<=b;i++)#define CL(x) memset(x, 0, sizeof(x))#define CLX(x, y) memset(x, y, sizeof(x))template <class T> T two(T x) {return 1<<x ;}template <class T> void Min(T &x, T y){if(y < x) x = y;}template <class T> void Max(T &x,T y){if(y > x) x = y;}int dp[45][1<<6][1<<6],n,m;int full;inline int get(int x){ int cnt = 0; rep(i,m) if(x>>i&1) cnt++; return m - cnt;}bool check(int a,int b,int c){ int s = b | (b<<1) | (b>>1) | a | c; return ( s & (full-1) )== (full-1);}int State[1<<6];int main() { scanf("%d%d",&n,&m); if(n < m) swap(n,m); full = two(m) ; rep(i,n+1) rep(j,full) rep(k,full) dp[i][j][k] = -111111; rep(i,full) dp[0][0][i] = 0,State[i] = get(i); rep(i,n) rep(j,full) rep(k,full) rep(l,full) if(check(j,k,l)) Max( dp[i+1][k][l] , dp[i][j][k] + State[k] ); int ans = 0; rep(i,full) Max(ans,dp[n][i][0]); cout<<ans<<endl;}