可以用状压dp,但是要打一下表。暴力枚举行、这一行的状态、上一行的状态,判断如果上一行的状态能转移到这一行的状态就转移。
状态定义:ans[i][S]表示i行前已经全部填满,i行已经填上的列为集合S。如果有竖着的,全部当做用这一行的去补满上一行缺的。
(貌似还是插头dp的入门题)
1 #include<cstdio> 2 #include<cstring> 3 typedef long long LL; 4 LL f[20][20]; 5 LL h,w; 6 /*LL ans[12][2050]; 7 LL h,w; 8 bool judge(LL a,LL b) 9 { 10 LL i,num=0,t1,t2; 11 for(i=1;i<=w;i++) 12 { 13 t1=a&1; 14 t2=b&1; 15 a>>=1; 16 b>>=1; 17 if(t1==1&&t2==1) 18 num++; 19 else if(t1==0&&t2==0) 20 return false; 21 else 22 { 23 if(num&1) 24 return false; 25 num=0; 26 } 27 } 28 if(num&1) 29 return false; 30 else 31 return true; 32 } 33 LL get(LL h,LL w) 34 { 35 LL i,j,k; 36 memset(ans,0,sizeof(ans)); 37 ans[0][(1<<w)-1]=1; 38 for(i=1;i<=h;i++) 39 for(j=0;j<(1<<w);j++) 40 for(k=0;k<(1<<w);k++) 41 if(judge(k,j)) 42 { 43 ans[i][j]+=ans[i-1][k]; 44 } 45 return ans[h][(1<<w)-1]; 46 } 47 int main() 48 { 49 for(h=1;h<=11;h++) 50 for(w=1;w<=11;w++) 51 printf("f[%lld][%lld]=%lld; ",h,w,get(h,w)); 52 return 0; 53 }*/ 54 int main() 55 { 56 f[1][1]=0; 57 f[1][2]=1; 58 f[1][3]=0; 59 f[1][4]=1; 60 f[1][5]=0; 61 f[1][6]=1; 62 f[1][7]=0; 63 f[1][8]=1; 64 f[1][9]=0; 65 f[1][10]=1; 66 f[1][11]=0; 67 f[2][1]=1; 68 f[2][2]=2; 69 f[2][3]=3; 70 f[2][4]=5; 71 f[2][5]=8; 72 f[2][6]=13; 73 f[2][7]=21; 74 f[2][8]=34; 75 f[2][9]=55; 76 f[2][10]=89; 77 f[2][11]=144; 78 f[3][1]=0; 79 f[3][2]=3; 80 f[3][3]=0; 81 f[3][4]=11; 82 f[3][5]=0; 83 f[3][6]=41; 84 f[3][7]=0; 85 f[3][8]=153; 86 f[3][9]=0; 87 f[3][10]=571; 88 f[3][11]=0; 89 f[4][1]=1; 90 f[4][2]=5; 91 f[4][3]=11; 92 f[4][4]=36; 93 f[4][5]=95; 94 f[4][6]=281; 95 f[4][7]=781; 96 f[4][8]=2245; 97 f[4][9]=6336; 98 f[4][10]=18061; 99 f[4][11]=51205; 100 f[5][1]=0; 101 f[5][2]=8; 102 f[5][3]=0; 103 f[5][4]=95; 104 f[5][5]=0; 105 f[5][6]=1183; 106 f[5][7]=0; 107 f[5][8]=14824; 108 f[5][9]=0; 109 f[5][10]=185921; 110 f[5][11]=0; 111 f[6][1]=1; 112 f[6][2]=13; 113 f[6][3]=41; 114 f[6][4]=281; 115 f[6][5]=1183; 116 f[6][6]=6728; 117 f[6][7]=31529; 118 f[6][8]=167089; 119 f[6][9]=817991; 120 f[6][10]=4213133; 121 f[6][11]=21001799; 122 f[7][1]=0; 123 f[7][2]=21; 124 f[7][3]=0; 125 f[7][4]=781; 126 f[7][5]=0; 127 f[7][6]=31529; 128 f[7][7]=0; 129 f[7][8]=1292697; 130 f[7][9]=0; 131 f[7][10]=53175517; 132 f[7][11]=0; 133 f[8][1]=1; 134 f[8][2]=34; 135 f[8][3]=153; 136 f[8][4]=2245; 137 f[8][5]=14824; 138 f[8][6]=167089; 139 f[8][7]=1292697; 140 f[8][8]=12988816; 141 f[8][9]=108435745; 142 f[8][10]=1031151241; 143 f[8][11]=8940739824; 144 f[9][1]=0; 145 f[9][2]=55; 146 f[9][3]=0; 147 f[9][4]=6336; 148 f[9][5]=0; 149 f[9][6]=817991; 150 f[9][7]=0; 151 f[9][8]=108435745; 152 f[9][9]=0; 153 f[9][10]=14479521761; 154 f[9][11]=0; 155 f[10][1]=1; 156 f[10][2]=89; 157 f[10][3]=571; 158 f[10][4]=18061; 159 f[10][5]=185921; 160 f[10][6]=4213133; 161 f[10][7]=53175517; 162 f[10][8]=1031151241; 163 f[10][9]=14479521761; 164 f[10][10]=258584046368; 165 f[10][11]=3852472573499; 166 f[11][1]=0; 167 f[11][2]=144; 168 f[11][3]=0; 169 f[11][4]=51205; 170 f[11][5]=0; 171 f[11][6]=21001799; 172 f[11][7]=0; 173 f[11][8]=8940739824; 174 f[11][9]=0; 175 f[11][10]=3852472573499; 176 f[11][11]=0; 177 scanf("%lld%lld",&h,&w); 178 while(h!=0&&w!=0) 179 { 180 printf("%lld ",f[h][w]); 181 scanf("%lld%lld",&h,&w); 182 } 183 }