记录编号 158765 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [CQOI2015]标识设计 最终得分 100
用户昵称 GravatarAsm.Def 是否通过 通过
代码语言 C++ 运行时间 5.302 s
提交时间 2015-04-17 17:12:44 内存使用 240.98 MiB
显示代码纯文本
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <cctype>
#include <algorithm>
#include <cmath>
using namespace std;
#define USEFREAD
#ifdef USEFREAD
#define InputLen 1000
char CHARPOOL[InputLen], *ptr=CHARPOOL;
#define getc() (*(ptr++))
#else
#define getc() (getchar())
#endif
#define SetFile(x) (freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout))
template<class T>inline void getd(T &x){
    char ch = getc();bool neg = false;
    while(!isdigit(ch) && ch != '-')ch = getc();
    if(ch == '-')ch = getc(), neg = true;
    x = ch - '0';
    while(isdigit(ch = getc()))x = x * 10 - '0' + ch;
    if(neg)x = -x;
}
/***********************************************************************/
typedef long long LL;
LL f[4][4095][2][31][31], Ans;//f[放了几个][列覆盖状态][是否要向右延伸][x][y] = 方案数
int N, M, ST[4096], trv[4096][31], Scnt = 1;
#define id(x) (lower_bound(ST, ST + Scnt, x) - ST)
#define bin(x) (1 << x)
bool G[31][31];

inline void init(){
	getd(N), getd(M);
	memset(f, -1, sizeof(f));
	int i, j, k, t;
	for(i = 0;i < N;++i){
		while((k = getc()) != '.' && k != '#');
		for(j = 0;j < M;++j){
			G[i][j] = (k == '#');
			k = getc();
		}
	}
	for(i = 0;i+1 < M;++i){
		ST[Scnt++] = bin(i);
		for(j = 0;j < i;++j){
			ST[Scnt++] = bin(i) | bin(j);
			for(k = 0;k < j;++k)ST[Scnt++] = bin(i) | bin(j) | bin(k);
		}
	}
	for(i = 0;i < Scnt;++i)for(j = 0,t = 1;j+1 < M;++j, t <<= 1)if(ST[i] & t)
		trv[trv[i][j] = id(ST[i] ^ t)][j] = i;
}
LL dp(bool lk, int cnt, int i, int j, int St){
	LL &ans = f[cnt][St][lk][i][j];
	if(~ans)return ans;
	ans = 0;
	if(i == N)return ans = (!lk && !St && !cnt);
	if(j == M){if(!lk)ans = dp(0,cnt,i+1,0,St);return ans;}
	register int b = bin(j), st = ST[St];
	if(lk && (b & st))return 0;
	if(lk){//from left
		if(G[i][j])return 0;
		return ans = dp(0,cnt,i,j+1,St) + dp(1,cnt,i,j+1,St);
	}
	if(b & st){//from above
		if(G[i][j])return 0;
		return ans = dp(1,cnt,i,j+1,trv[St][j]) + dp(0,cnt,i,j+1,St);
	}
	ans = dp(0,cnt,i,j+1,St);//skip 
	if(!G[i][j] && cnt && j+1 < M)ans += dp(0,cnt-1,i,j+1,trv[St][j]);// new
	return ans;
}

int main(){
	#ifdef DEBUG
	freopen("test.txt", "r", stdin);
	#else
	SetFile(cqoi15_logo);
	#endif
	#ifdef USEFREAD
	fread(ptr,1,InputLen,stdin);
	#endif
	init();
	printf("%lld\n", dp(0,3,0,0,0));
	
#ifdef DEBUG
    printf("\n%.3lf sec \n", (double)clock() / CLOCKS_PER_SEC);
#endif
    return 0;
}