题意:给定一个长宽小于等于11的矩形,问用1×2的小矩形填满,有多少种方法。
分析:状态压缩dp,f[i][j]表示第i行,状态为j的情况有多少种。设置一个match函数,用来检测可不可以由前一行的状态a到后一行的状态b,如果可以,则f[i][a]+=f[i - 1][b];
match可以分为一下情况考虑,两个都为0不可以,一个为0一个为1可以(不放,或竖着放),两个都为一(横着方,需要检查下一列是否为1,然后直接i<<=2越过一列)。
View Code
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
usingnamespace std;
#define maxn 11
longlong f[maxn][1<< maxn];
int n, m;
/*
bool ok(int a)
{
int x = 1;
int count = 0;
for (int i = 0; i < m; i++, x <<= 1)
{
if (a & x)
count++;
else
{
if (count & 1)
return false;
count = 0;
}
}
return !(count & 1);
}
void init()
{
for (int i = 0; i < 1 << m; i++)
if (ok(i))
f[0][i] = 1;
}
bool match(int a, int b)
{
for (int i = 1; i < 1 << m;)
{
if (((a & i) == 0) && ((b & i) == 0))
return false;
if ((a & i) && (b & i))
{
if ((a & (i << 1)) && ((b & (i << 1))))
{
i <<= 2;
continue;
}
else
return false;
}
i <<= 1;
}
return true;
}
void work()
{
for (int i = 1; i < n; i++)
for (int j = 0; j < 1 << m; j++)
for (int k = 0; k < 1 << m; k++)
if (match(k, j))
f[i][j] += f[i - 1][k];
}
int main()
{
freopen("t.txt", "w", stdout);
for (int i = 1; i < 12; i++)
for (int j = 1; j < 12; j++)
{
n = i;
m = j;
printf("f[%d][%d]=", n, m);
memset(f, 0, sizeof(f));
if (m > n)
swap(m, n);
init();
work();
printf("%lld;\n", f[n - 1][(1 << m) - 1]);
}
return 0;
}*/
int main()
{
//freopen("t.txt", "r", stdin);
f[1][1] =0;
f[1][2] =1;
f[1][3] =0;
f[1][4] =1;
f[1][5] =0;
f[1][6] =1;
f[1][7] =0;
f[1][8] =1;
f[1][9] =0;
f[1][10] =1;
f[1][11] =0;
f[2][1] =1;
f[2][2] =2;
f[2][3] =3;
f[2][4] =5;
f[2][5] =8;
f[2][6] =13;
f[2][7] =21;
f[2][8] =34;
f[2][9] =55;
f[2][10] =89;
f[2][11] =144;
f[3][1] =0;
f[3][2] =3;
f[3][3] =0;
f[3][4] =11;
f[3][5] =0;
f[3][6] =41;
f[3][7] =0;
f[3][8] =153;
f[3][9] =0;
f[3][10] =571;
f[3][11] =0;
f[4][1] =1;
f[4][2] =5;
f[4][3] =11;
f[4][4] =36;
f[4][5] =95;
f[4][6] =281;
f[4][7] =781;
f[4][8] =2245;
f[4][9] =6336;
f[4][10] =18061;
f[4][11] =51205;
f[5][1] =0;
f[5][2] =8;
f[5][3] =0;
f[5][4] =95;
f[5][5] =0;
f[5][6] =1183;
f[5][7] =0;
f[5][8] =14824;
f[5][9] =0;
f[5][10] =185921;
f[5][11] =0;
f[6][1] =1;
f[6][2] =13;
f[6][3] =41;
f[6][4] =281;
f[6][5] =1183;
f[6][6] =6728;
f[6][7] =31529;
f[6][8] =167089;
f[6][9] =817991;
f[6][10] =4213133;
f[6][11] =21001799;
f[7][1] =0;
f[7][2] =21;
f[7][3] =0;
f[7][4] =781;
f[7][5] =0;
f[7][6] =31529;
f[7][7] =0;
f[7][8] =1292697;
f[7][9] =0;
f[7][10] =53175517;
f[7][11] =0;
f[8][1] =1;
f[8][2] =34;
f[8][3] =153;
f[8][4] =2245;
f[8][5] =14824;
f[8][6] =167089;
f[8][7] =1292697;
f[8][8] =12988816;
f[8][9] =108435745;
f[8][10] =1031151241;
f[8][11] =8940739824;
f[9][1] =0;
f[9][2] =55;
f[9][3] =0;
f[9][4] =6336;
f[9][5] =0;
f[9][6] =817991;
f[9][7] =0;
f[9][8] =108435745;
f[9][9] =0;
f[9][10] =14479521761;
f[9][11] =0;
f[10][1] =1;
f[10][2] =89;
f[10][3] =571;
f[10][4] =18061;
f[10][5] =185921;
f[10][6] =4213133;
f[10][7] =53175517;
f[10][8] =1031151241;
f[10][9] =14479521761;
f[10][10] =258584046368;
f[10][11] =3852472573499;
f[11][1] =0;
f[11][2] =144;
f[11][3] =0;
f[11][4] =51205;
f[11][5] =0;
f[11][6] =21001799;
f[11][7] =0;
f[11][8] =8940739824;
f[11][9] =0;
f[11][10] =3852472573499;
f[11][11] =0;
while (scanf("%d%d", &n, &m), (n | m) >0)
printf("%lld\n", f[n][m]);
return0;
}
#include <cstdio>
#include <cstdlib>
#include <cstring>
usingnamespace std;
#define maxn 11
longlong f[maxn][1<< maxn];
int n, m;
/*
bool ok(int a)
{
int x = 1;
int count = 0;
for (int i = 0; i < m; i++, x <<= 1)
{
if (a & x)
count++;
else
{
if (count & 1)
return false;
count = 0;
}
}
return !(count & 1);
}
void init()
{
for (int i = 0; i < 1 << m; i++)
if (ok(i))
f[0][i] = 1;
}
bool match(int a, int b)
{
for (int i = 1; i < 1 << m;)
{
if (((a & i) == 0) && ((b & i) == 0))
return false;
if ((a & i) && (b & i))
{
if ((a & (i << 1)) && ((b & (i << 1))))
{
i <<= 2;
continue;
}
else
return false;
}
i <<= 1;
}
return true;
}
void work()
{
for (int i = 1; i < n; i++)
for (int j = 0; j < 1 << m; j++)
for (int k = 0; k < 1 << m; k++)
if (match(k, j))
f[i][j] += f[i - 1][k];
}
int main()
{
freopen("t.txt", "w", stdout);
for (int i = 1; i < 12; i++)
for (int j = 1; j < 12; j++)
{
n = i;
m = j;
printf("f[%d][%d]=", n, m);
memset(f, 0, sizeof(f));
if (m > n)
swap(m, n);
init();
work();
printf("%lld;\n", f[n - 1][(1 << m) - 1]);
}
return 0;
}*/
int main()
{
//freopen("t.txt", "r", stdin);
f[1][1] =0;
f[1][2] =1;
f[1][3] =0;
f[1][4] =1;
f[1][5] =0;
f[1][6] =1;
f[1][7] =0;
f[1][8] =1;
f[1][9] =0;
f[1][10] =1;
f[1][11] =0;
f[2][1] =1;
f[2][2] =2;
f[2][3] =3;
f[2][4] =5;
f[2][5] =8;
f[2][6] =13;
f[2][7] =21;
f[2][8] =34;
f[2][9] =55;
f[2][10] =89;
f[2][11] =144;
f[3][1] =0;
f[3][2] =3;
f[3][3] =0;
f[3][4] =11;
f[3][5] =0;
f[3][6] =41;
f[3][7] =0;
f[3][8] =153;
f[3][9] =0;
f[3][10] =571;
f[3][11] =0;
f[4][1] =1;
f[4][2] =5;
f[4][3] =11;
f[4][4] =36;
f[4][5] =95;
f[4][6] =281;
f[4][7] =781;
f[4][8] =2245;
f[4][9] =6336;
f[4][10] =18061;
f[4][11] =51205;
f[5][1] =0;
f[5][2] =8;
f[5][3] =0;
f[5][4] =95;
f[5][5] =0;
f[5][6] =1183;
f[5][7] =0;
f[5][8] =14824;
f[5][9] =0;
f[5][10] =185921;
f[5][11] =0;
f[6][1] =1;
f[6][2] =13;
f[6][3] =41;
f[6][4] =281;
f[6][5] =1183;
f[6][6] =6728;
f[6][7] =31529;
f[6][8] =167089;
f[6][9] =817991;
f[6][10] =4213133;
f[6][11] =21001799;
f[7][1] =0;
f[7][2] =21;
f[7][3] =0;
f[7][4] =781;
f[7][5] =0;
f[7][6] =31529;
f[7][7] =0;
f[7][8] =1292697;
f[7][9] =0;
f[7][10] =53175517;
f[7][11] =0;
f[8][1] =1;
f[8][2] =34;
f[8][3] =153;
f[8][4] =2245;
f[8][5] =14824;
f[8][6] =167089;
f[8][7] =1292697;
f[8][8] =12988816;
f[8][9] =108435745;
f[8][10] =1031151241;
f[8][11] =8940739824;
f[9][1] =0;
f[9][2] =55;
f[9][3] =0;
f[9][4] =6336;
f[9][5] =0;
f[9][6] =817991;
f[9][7] =0;
f[9][8] =108435745;
f[9][9] =0;
f[9][10] =14479521761;
f[9][11] =0;
f[10][1] =1;
f[10][2] =89;
f[10][3] =571;
f[10][4] =18061;
f[10][5] =185921;
f[10][6] =4213133;
f[10][7] =53175517;
f[10][8] =1031151241;
f[10][9] =14479521761;
f[10][10] =258584046368;
f[10][11] =3852472573499;
f[11][1] =0;
f[11][2] =144;
f[11][3] =0;
f[11][4] =51205;
f[11][5] =0;
f[11][6] =21001799;
f[11][7] =0;
f[11][8] =8940739824;
f[11][9] =0;
f[11][10] =3852472573499;
f[11][11] =0;
while (scanf("%d%d", &n, &m), (n | m) >0)
printf("%lld\n", f[n][m]);
return0;
}