新学状态压缩DP。
http://www.cnblogs.com/avril/p/3282295.html
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int maxl = (1<<9) + 5;
int n, m, k, mark[maxl], len;
LL dp[88][22][maxl];
inline void getInit(){
memset(dp, 0, sizeof(dp));
len = 0;
memset(mark, 0, sizeof(mark));
}
inline int num(int x){//十进制下计数状态
int sum = 0;
while(x){
if(x&1) sum++;
x = x >> 1;
}
return sum;
}
inline bool judge(int x){
if(x & (x << 1)) return 0;//巧判相邻
return 1;
}
int main(){
while(scanf("%d%d%d", &n, &m, &k) != EOF){
getInit();
if(m > n) swap(n, m);
for(int i = 0; i < (1<<m); i++)//初始化
if(judge(i)){
dp[1][num(i)][len] = 1;
mark[len++] = i;
}
for(int i = 2; i <= n; i++)
for(int j = 0; j <= k; j++)
for(int r = 0; r < len; r++)
for(int l = 0; l < len; l++){
int tmp = num(mark[r]);
if(mark[r] & mark[l] || j < tmp) continue;
dp[i][j][r] += dp[i-1][j-tmp][l];
}
LL ans = 0;
for(int i = 0; i < len; i++)
ans += dp[n][k][i];
printf("%lld\n", ans);
}
return 0;
}