2011年全国大学生程序设计邀请赛(福州)——Tiling
2012-08-19 18:09
381 查看
Tiling
Time Limit: 1000msMemory Limit: 32768KBThis problem will be judged on FZU. Original ID: 204064-bit integer IO format: %I64d Java class name: MainPrev Submit Status Statistics Discuss NextFont Size: + -Type: None Graph Theory 2-SAT Articulation/Bridge/Biconnected Component Cycles/Topological Sorting/Strongly Connected Component Shortest Path Bellman Ford Dijkstra/Floyd Warshall Euler Trail/Circuit Heavy-Light Decomposition Minimum Spanning Tree Stable Marriage Problem Trees Directed Minimum Spanning Tree Flow/Matching Graph Matching Bipartite Matching Hopcroft–Karp Bipartite Matching Weighted Bipartite Matching/Hungarian Algorithm Flow Max Flow/Min Cut Min Cost Max Flow DFS-like Backtracking with Pruning/Branch and Bound Basic Recursion IDA* Search Parsing/Grammar Breadth First Search/Depth First Search Advanced Search Techniques Binary Search/Bisection Ternary Search Geometry Basic Geometry Computational Geometry Convex Hull Pick's Theorem Game Theory Green Hackenbush/Colon Principle/Fusion Principle Nim Sprague-Grundy Number Matrix Gaussian Elimination Matrix Exponentiation Data Structures Basic Data Structures Binary Indexed Tree Binary Search Tree Hashing Orthogonal Range Search Range Minimum Query/Lowest Common Ancestor Segment Tree/Interval Tree Trie Tree Sorting Disjoint Set String Aho Corasick Knuth-Morris-Pratt Suffix Array/Suffix Tree Math Basic Math Big Integer Arithmetic Number Theory Chinese Remainder Theorem Extended Euclid Inclusion/Exclusion Modular Arithmetic Combinatorics Group Theory/Burnside's lemma Counting Probability/Expected Value Others Tricky Hardest Unusual Brute Force Implementation Constructive Algorithms Two Pointer Bitmask Beginner Discrete Logarithm/Shank's Baby-step Giant-step Algorithm Greedy Divide and Conquer Dynamic Programming Tag it!We can perfectly tile one m*n rectangle by any size of tiles. The following picture shows all the 34 possible ways to perfectly title a 3*2 rectangle.
Now you are given one m*n rectangle, your task is to calculate the total number of the ways to perfectly title the given rectangle. Please mod the answer with 1,000,000,007 when you output it.
Input
The first line of the input contains an integer T(T≤100), indicating the number of test cases. Following is T lines, each containing two integer numbers m(1≤m≤6) and n(1≤n≤1,000,000,000).Output
For each test case, print a line containing the test case number (beginning with 1) and the answer.Sample Input
2 2 2 3 2
Sample Output
Case 1: 8 Case 2: 34
矩阵乘法,借用bianchengla的模板
矩阵表示最后两行的状态转移,即上一行的某个状态可以通过几种方式转移到最后一行的状态,构成一个矩阵。由于每一行最多六个格子,状态只需要考虑5个分割线是否存在,所以最大是32*32。如果上一行某两个位置有分割线,下一行相同的两个位置也有,(且中间没有其他的隔断),那么此处有两种可能,即上下联通或者不联通,结果mat[i][j]*2,上代码:
#include <iostream> #include <cstdio> #include<algorithm> using namespace std; typedef long long LL; const int maxn = 1 << 5; const LL MOD = 1000000007; struct mat { int n; LL data[maxn][maxn]; friend mat operator * (const mat& a, const mat& b) { mat r; r.n = a.n; for (int i = 0; i < r.n; ++i) { for (int j = 0; j < r.n; ++j) { r.data[i][j] = 0; for (int k = 0; k < r.n; ++k) { r.data[i][j] += a.data[i][k] * b.data[k][j] % MOD; } r.data[i][j] %= MOD; } } return r; } friend mat pow(mat a, int b) { mat r; r.n = a.n; for (int i = 0; i < r.n; ++i) { for (int j = 0; j < r.n; ++j) { r.data[i][j] = 0; } r.data[i][i] = 1; } for (;b;) { if ( b & 1 ) r = r * a; if ( b >>= 1 ) a = a * a; } return r; } } ; //上面是bianchengla的矩阵乘法和快速幂模板 /////////////////////////////////////////////////////////// mat m[6]; void buildmat(int n){ m .n = 1<<n; for(int x=0; x<(1<<n); x++){ for(int y=0; y<(1<<n); y++){ //填充x到y的状态转移方式 // m .data[x][y] = 1; int t[8] = {0}; for(int i=0; i<n; i++){ if( x&(1<<i) ) t[i+1] ++; if( y&(1<<i) ) t[i+1] ++; } t[0] = 2; t[n+1] = 2; //t[]存储两行中这个位置有几条分割线,头尾要各补充一条 int re = 0; for(int i=0; i<=n+1; i++){ if(t[i]==2) re++; //==2就+1 if(t[i]==1) re=0; //==1就中断了 if(re==2) m .data[x][y] *= 2, re=1; //凑齐两个就×2,re变成1 } } } } int main() { for(int ii=0; ii<6; ii++) buildmat(ii); // built mat in m[i] int T; scanf("%d", &T); int r, n; for(int ti=1; ti<=T; ti++){ scanf("%d%d", &r, &n); mat res = pow(m[r-1], n-1); //我的习惯所有的数组都从0处开始储存,所以这儿会出现-1 LL sum = 0; for(int i=0; i<res.n; i++) for(int j=0; j<res.n; j++) sum = (sum+res.data[i][j]) % MOD; cout << "Case " << ti << ": " << (sum%MOD) << endl; } }
相关文章推荐
- FZU - 2039 Pets (二分图匹配 2011年全国大学生程序设计邀请赛(福州))
- FZU2011年全国大学生程序设计邀请赛(福州) 2038Another Postman Problem
- 2011年全国大学生程序设计邀请赛(福州)
- FZU 2011年全国大学生程序设计邀请赛(福州) 2039 Pets
- FZU 2011年全国大学生程序设计邀请赛(福州) 2034 Password table
- FZU - 2039 Pets (二分图匹配 2011年全国大学生程序设计邀请赛(福州))
- 2016码农谷全国大学生程序设计邀请赛(第一轮资格赛)
- 2016码农谷全国大学生程序设计邀请赛(测试赛)
- 2016码农谷全国大学生程序设计邀请赛
- EOJ-大学生程序设计邀请赛(华东师范大学)-F-丽娃河的狼人传说
- 大学生程序设计邀请赛(华东师范大学)
- 大学生程序设计邀请赛(华东师范大学)-F-贪心
- 大学生程序设计邀请赛(华东师范大学)
- EOJ 3247 大学生程序设计邀请赛(华东师范大学)-G 铁路修复计划
- EOJ-大学生程序设计邀请赛(华东师范大学)-C-袋鼠妈妈找孩子
- 2011年全国大学生电子设计竞赛总结
- 大学生程序设计邀请赛(华东师范大学) 黑心啤酒厂
- EOJ-大学生程序设计邀请赛(华东师范大学)-E-黑心啤酒厂
- 2017大学生程序设计邀请赛(华东师范大学) A.拼音魔法
- 大学生程序设计邀请赛(华东师范大学)A. 拼音魔法