poj 2411 2663 2420 dp+dfs+矩阵快速幂(1*2矩形排版次数)
来源:互联网 发布:桨战船 知乎 编辑:程序博客网 时间:2024/05/20 16:41
从这篇博客学到很多:
点击打开链接
直接枚举高的状态,一旦此状态确定了,之后的状态就都确定了。
poj2411:
题意:
给定一个长宽小于等于11的矩形,问用1×2的小矩形填满,有多少种方法。
代码:
#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>#include <climits>#include <cassert>#define LL long long#define lson lo, mi, rt << 1#define rson mi + 1, hi, rt << 1 | 1using namespace std;const int inf = 0x3f3f3f3f;const int maxn = 12;int h, w;LL dp[maxn][1 << maxn];vector<pair<int, int> > path;void dfs(int dep, int nowState, int preState){ if (dep > w) return; if (dep == w) { path.push_back(make_pair(nowState, preState)); return; } dfs(dep + 2, (nowState << 2) | 3, (preState << 2) | 3); dfs(dep + 1, (nowState << 1) | 1, preState << 1); dfs(dep + 1, nowState << 1, (preState << 1) | 1);}int main(){#ifdef LOCAL freopen("in.txt", "r", stdin);#endif // LOCAL while (~scanf("%d%d", &h, &w)) { if (!h && !w) break; if (h < w) swap(h, w); path.clear(); dfs(0, 0, 0); memset(dp, 0, sizeof(dp)); dp[0][(1 << w) - 1] = 1; for (int i = 1; i <= h; i++) { for (int j = 0; j < path.size(); j++) { int now = path[j].first; int pre = path[j].second; dp[i][now] += dp[i - 1][pre]; } } printf("%lld\n", dp[h][(1 << w) - 1]); } return 0;}
poj 2663:
题意:
给定1*2的小矩形,去拼接一个3*n(n<30)的矩形,问有多少种方案。
代码:
#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>#include <climits>#include <cassert>#define LL long long#define lson lo, mi, rt << 1#define rson mi + 1, hi, rt << 1 | 1using namespace std;const int inf = 0x3f3f3f3f;typedef vector<LL> vec;typedef vector<vec> mat;int h, w;mat A(20, vec(20));void dfs(int dep, int nowState, int preState){ if (dep > w) return; if (dep == w) { A[preState][nowState]++; return; } dfs(dep + 2, (nowState << 2) | 3, (preState << 2) | 3); dfs(dep + 1, (nowState << 1) | 1, preState << 1); dfs(dep + 1, nowState << 1, (preState << 1) | 1);}mat mul(mat &A, mat &B){ mat C(A.size(), vec(B[0].size())); for (int i = 0; i < A.size(); i++) { for (int k = 0; k < B.size(); k++) { for (int j = 0; j < B[0].size(); j++) {// C[i][j] = (C[i][j] + A[i][k] * B[k][j]) % mod; C[i][j] = (C[i][j] + A[i][k] * B[k][j]); } } } return C;}mat pow(mat A, LL n){ mat B(A.size(), vec(A.size())); for (int i = 0; i < A.size(); i++) { B[i][i] = 1; } while (0 < n) { if (n & 1) B = mul(B, A); A = mul(A, A); n >>= 1; } return B;}int main(){#ifdef LOCAL freopen("in.txt", "r", stdin);#endif // LOCAL w = 3; dfs(0, 0, 0); while (~scanf("%d", &h)) { if (h == -1) break; mat ans = pow(A, h); printf("%lld\n", ans[(1 << w) - 1][(1 << w) - 1]); } return 0;}
poj 2420:
题意:
给定1*2的小矩形,去拼接一个4*n(n<10^9)的矩形,问有多少种方案。
解析:
N这么大递推肯定是不行了,所以我们要用矩阵快速幂进行加速,这个转移矩阵如何构造呢,我们可以直接用pre状态转移到now状态采用邻接矩阵的方式表述就好了。这个矩阵的大小为at[16][16],at[15][15]就是最后要求的状态。
代码:
#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>#include <climits>#include <cassert>#define LL long long#define lson lo, mi, rt << 1#define rson mi + 1, hi, rt << 1 | 1using namespace std;const int inf = 0x3f3f3f3f;typedef vector<LL> vec;typedef vector<vec> mat;int h, w;int mod;mat A(20, vec(20));void dfs(int dep, int nowState, int preState){ if (dep > w) return; if (dep == w) { A[preState][nowState]++; return; } dfs(dep + 2, (nowState << 2) | 3, (preState << 2) | 3); dfs(dep + 1, (nowState << 1) | 1, preState << 1); dfs(dep + 1, nowState << 1, (preState << 1) | 1);}mat mul(mat &A, mat &B){ mat C(A.size(), vec(B[0].size())); for (int i = 0; i < A.size(); i++) { for (int k = 0; k < B.size(); k++) { for (int j = 0; j < B[0].size(); j++) { C[i][j] = (C[i][j] + A[i][k] * B[k][j]) % mod;// C[i][j] = (C[i][j] + A[i][k] * B[k][j]); } } } return C;}mat pow(mat A, LL n){ mat B(A.size(), vec(A.size())); for (int i = 0; i < A.size(); i++) { B[i][i] = 1; } while (0 < n) { if (n & 1) B = mul(B, A); A = mul(A, A); n >>= 1; } return B;}int main(){#ifdef LOCAL freopen("in.txt", "r", stdin);#endif // LOCAL w = 4; dfs(0, 0, 0); while (~scanf("%d%d", &h, &mod)) { if (!h && !mod) break; mat ans = pow(A, h); printf("%lld\n", ans[(1 << w) - 1][(1 << w) - 1]); } return 0;}
0 0
- poj 2411 2663 2420 dp+dfs+矩阵快速幂(1*2矩形排版次数)
- POJ 2411 大矩形用1X2小矩形填充 状态dp DFS
- POJ 2411 大矩形用1X2小矩形填充 状态dp DFS
- poj 3744 Scout YYF 1 (概率DP+矩阵快速幂)
- POJ 3744 Scout YYF(概率DP+矩阵快速幂)
- POJ 3734 Blocks(dp、矩阵快速幂)
- 【状压dp && 矩阵快速幂】 POJ
- POJ 3744 概率dp+矩阵快速幂
- poj 3420 dp+矩阵(矩形填充)
- poj 2778 DNA Sequence 【ac自动机 + dp + 矩阵快速幂】
- poj 2778 AC自动机+DP+矩阵快速幂
- POJ 3744 Scout YYF I 矩阵快速幂加速dp
- poj 2778 (AC自动机+dp+矩阵快速幂)
- poj 3744 Scout YYF I(概率DP&矩阵快速幂)
- POJ 3734 —— 矩阵快速幂 + DP
- poj 3744 Scout YYF I(概率dp+矩阵快速幂)
- [AC自动机+dp+矩阵快速幂] poj 2778 DNA Sequence
- POJ 3420 Quad Tiling 状压DP+矩阵快速幂
- 输出m到n的水仙花数
- Hdu oj 1012 u Calculate e
- 黑马程序员-网络编程(二)
- QT5---QTableWidget简单应用之文件浏览器
- C语言-DynamicMemory
- poj 2411 2663 2420 dp+dfs+矩阵快速幂(1*2矩形排版次数)
- 八大排序算法(二)希尔排序
- UVA 1587 Box
- php输出
- 1.【SELinux学习笔记】背景
- uva 12118 Inspector's Dilemma
- DHTMLX中,通过For循环,将JSON值以tree的形式展示
- hadoop 编程规范(hadoop专利分析)
- Palindrome