1 /*
2 题意:用1*2覆盖n*m的区域的方案数,n<=1000,m<=5
3 思路:枚举每层的状态,计算状态之间的转移。则dp[i][j]=sum(dp[i-1][k]*a[k][j])其中k为前一层状态,j为当前层状态。
4 状态之间的转移,可以枚举当前层的放置方案,
5 时间:2018.07.18
6 */
7 #include <bits/stdc++.h>
8 using namespace std;
9
10 typedef long long LL;
11 const int MAXN=100005;
12 const LL MOD7 = 1e9+7;
13
14 int a[1<<5][1<<5];
15 LL dp[1005][1<<5];
16 int n,m;
17
18 void dfs(int state1,int state2,int state,int depth)
19 {
20 // printf("state1=%d state2=%d state=%d depth=%d\n",state1,state2,state,depth);
21 // printf("%d %d\n",(state&(1<<depth)), (state2&(1<<depth)));
22 if (depth==m)
23 {
24 if (state==(1<<m)-1) ++a[state1][state2];
25 return ;
26 }
27 if ((state&(1<<depth))==0 && (state2&(1<<depth))!=0) dfs(state1,state2,state+(1<<depth),depth+1);
28 if ((state&(1<<depth))==0 && (state2&(1<<depth))==0)
29 {
30 if (depth+1<m && (state&(1<<(depth+1)))==0) dfs(state1,state2,state+(1<<depth)+(1<<(depth+1)),depth+1);
31 return;
32 }
33 if ((state&(1<<depth))!=0 && (state2&(1<<depth))!=0) return;
34 dfs(state1, state2, state, depth+1);
35 }
36
37 void init()
38 {
39 for (int i=0;i<(1<<m);++i)
40 {
41 for (int j=0;j<(1<<m);++j)
42 {
43 dfs(i,j,i,0);
44 }
45 }
46 // for (int i=0;i<(1<<m);++i)
47 // {
48 // for (int j=0;j<(1<<m);++j)
49 // {
50 // printf("%d ",a[i][j]);
51 // }
52 // printf("\n");
53 // }
54 }
55
56 int main()
57 {
58 #ifndef ONLINE_JUDGE
59 freopen("test.txt","r",stdin);
60 #endif // ONLINE_JUDGE
61 scanf("%d%d",&n,&m);
62 init();
63 LL ans=0;
64 dp[0][(1<<m)-1]=1;
65 for (int i=1;i<=n+1;++i)
66 {
67 for (int j=0;j<(1<<m);++j)
68 {
69 for (int k=0;k<(1<<m);++k)
70 {
71 dp[i][j]=(dp[i][j]+a[k][j]*dp[i-1][k])%MOD7;
72 }
73 }
74 }
75 printf("%lld\n",dp[n+1][0]);
76 return 0;
77 }