BZOJ题面好像不全。
什么POI,CEOI吧。。还是去看原题比较好,比如
http://www.hsin.hr/ceoi2006/index.php?page=tasks
http://www.hsin.hr/ceoi2006/tasks/day2/connect.pdf
http://www.hsin.hr/ceoi2006/tasks/day2/connect_test.zip
http://www.hsin.hr/ceoi2006/tasks/solutions.pdf
http://www.hsin.hr/ceoi2006/tasks/solutions.zip
考虑每个方格的状态,发现有11种状态,分别是
空(1)、路径穿过(6)、X所在格(4)。
#include <cstdio>
#include <cstring>
#define rep(i,j,k) for(i=j;i<k;++i)
using namespace std;
const int N = 16, M = 64;
int n, m;
char a[2 * N][2 * M];
int how[N][M];
short dp[N][M][1 << 12][2];
const short inf = 10000;
char b[3][11][4] = {
{ "# #", "# #", "#.#", "# #", "# #", "# #", "#.#", "#.#", "#.#", "# #", "# #" },
{ " ", ".X ", " X ", " X.", " X ", "...", " . ", ".. ", " ..", " ..", ".. " },
{ "# #", "# #", "# #", "# #", "#.#", "# #", "#.#", "# #", "# #", "#.#", "#.#" },
};
int set_bit(int s, int i, int v) { return (s & ~(1 << i)) | (v << i); }
short rec( int r, int c, int mask, int U, int reconstruct ) {
if( r == n ) return rec( 0, c+1, mask, 0, reconstruct );
if( c == m ) return 0;
short &ret = dp[r][c][mask][U];
if( !reconstruct && ret >= 0 ) return ret;
ret = inf;
int L = (mask>>r)&1;
int R = a[2*r+1][2*c+2] == ' ';
int D = a[2*r+2][2*c+1] == ' ';
int X = a[2*r+1][2*c+1] == 'X';
int type=0, h1 = 0, state = 0, u = 0;
#define tst(tp, t1, mk, uu) { \
int v = t1 + rec(r + 1, c, mk, uu, 0 ); \
if( v < ret ) { ret = v; type = tp; h1=t1; state = mk; u = uu; } \
}
if (!X && !L && !U && 1 && 1) tst( 0, 0, set_bit(mask, r, 0), 0); // empty
if ( X && L && !U && 1 && 1) tst( 1, 1, set_bit(mask, r, 0), 0); // left
if ( X && !L && U && 1 && 1) tst( 2, 1, set_bit(mask, r, 0), 0); // up
if ( X && !L && !U && R && 1) tst( 3, 1, set_bit(mask, r, 1), 0); // right
if ( X && !L && !U && 1 && D) tst( 4, 1, set_bit(mask, r, 0), 1); // down
if (!X && L && !U && R && 1) tst( 5, 2, set_bit(mask, r, 1), 0 ); // left-right
if (!X && !L && U && 1 && D) tst( 6, 2, set_bit(mask, r, 0), 1 ); // up-down
if (!X && L && U && 1 && 1) tst( 7, 2, set_bit(mask, r, 0), 0); // left-up
if (!X && !L && U && R && 1) tst( 8, 2, set_bit(mask, r, 1), 0); // up-right
if (!X && !L && !U && R && D) tst( 9, 2, set_bit(mask, r, 1), 1); // right-down
if (!X && L && !U && 1 && D) tst(10, 2, set_bit(mask, r, 0), 1); // down-left
if (reconstruct) {
how[r][c] = type;
rec(r + 1, c, state, u, 1 );
}
return ret;
}
int main( void ) {
int i, j, k, l;
scanf( "%d%d ", &n, &m );
rep(i,0,n) fgets(a[i], 2 * M, stdin);
n /= 2; m /= 2;
memset(dp, -1, sizeof dp);
printf("%d\n", rec(0, 0, 0, 0, 1));
rep(i,0,n) rep(j,0,m) rep(k,0,3) rep(l,0,3)
if (b[k][how[i][j]][l] != ' ')
a[2 * i + k][2 * j + l] = b[k][how[i][j]][l];
rep(i,0,2*n+1) puts(a[i]);
return 0;
}