码迷,mamicode.com
首页 > 其他好文 > 详细

hihoCoder #1162 : 骨牌覆盖问题·三

时间:2015-10-08 21:29:12      阅读:400      评论:0      收藏:0      [点我收藏+]

标签:

#1162 : 骨牌覆盖问题·三

Time Limit:10000ms
Case Time Limit:1000ms
Memory Limit:256MB

描述

前两周里,我们讲解了2xN,3xN骨牌覆盖的问题,并且引入了两种不同的递推方法。
这一次我们再加强一次题目,对于给定的K和N,我们需要去求KxN棋盘的覆盖方案数。

提示:KxN骨牌覆盖

输入

第1行:2个整数N。表示棋盘宽度为k,长度为N。2≤K≤7,1≤N≤100,000,000

输出

第1行:1个整数,表示覆盖方案数 MOD 12357

Sample Input
2 62247088
Sample Output
1399

解题:dfs造转移方程+dp计数+快速幂优化dp
技术分享
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 const LL mod = 12357;
 5 int n,m;
 6 struct Matrix{
 7     int m[1<<7][1<<7];
 8     Matrix(){
 9         init();
10     }
11     void init(){
12         memset(m,0,sizeof m);
13     }
14     Matrix operator*(const Matrix &rhs){
15         Matrix ret;
16         for(int k = 0; k < (1<<n); ++k)
17             for(int i = 0; i < (1<<n); ++i)
18                 for(int j = 0; j < (1<<n); ++j)
19                     ret.m[i][j] = (ret.m[i][j] + m[i][k]*rhs.m[k][j])%mod;
20         return ret;
21     }
22     void print(){
23         for(int i = 0; i < 8; ++i){
24             for(int j = 0; j < 8; ++j)
25                 printf("%d ",m[i][j]);
26             cout<<endl;
27         }
28     }
29 };
30 Matrix a,b;
31 void quickPow(LL index){
32     while(index){
33         if(index&1) a = a*b;
34         index >>= 1;
35         b = b*b;
36     }
37 }
38 bool tab[10][10];
39 void dfs(int cur,int st){
40     if(cur >= n){
41         int ss = 0;
42         for(int i = n-1; i >= 0; --i){
43             ss <<= 1;
44             ss |= tab[i][1];
45         }
46         b.m[st][ss]++;
47         return;
48     }
49     if(!tab[cur][0]){
50         if(!tab[cur][1]){
51             tab[cur][0] = tab[cur][1] = true;
52             dfs(cur+1,st);
53             tab[cur][0] = tab[cur][1] = false;
54         }
55         if(cur + 1 < n){
56             if(!tab[cur+1][0]){
57                 tab[cur+1][0] = tab[cur][0] = true;
58                 dfs(cur+2,st);
59                 tab[cur+1][0] = tab[cur][0] = false;
60             }
61         }
62     }else dfs(cur + 1,st);
63 }
64 void init(int st){
65     memset(tab,false,sizeof tab);
66     for(int i = 0,xst = st; i < n; ++i,xst >>= 1)
67         tab[i][0] = xst&1;
68     dfs(0,st);
69 }
70 int main(){
71     while(~scanf("%d%d",&n,&m)){
72         b.init();
73         a.init();
74         for(int i = 0; i < (1<<n); ++i) init(i);
75         a.m[0][0] = 1;
76         quickPow(m);
77         printf("%d\n",a.m[0][0]);
78     }
79     return 0;
80 }
View Code

 

hihoCoder #1162 : 骨牌覆盖问题·三

标签:

原文地址:http://www.cnblogs.com/crackpotisback/p/4862296.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!