poj 2411 && 2663 && 3420 && 点头1033
来源:互联网 发布:淘宝假太岁什么做的 编辑:程序博客网 时间:2024/06/02 17:54
poj 2411 http://poj.org/problem?id=2411
题意:让你用1*2的矩阵去填满n*m的方格,有多少种方法
题解:http://blog.csdn.net/shiwei408/article/details/8821853
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;typedef long long LL;#define M 1<<11+1LL dp[14][M];int st[M*11][2];int n,m,cnt;void dfs(int cur,int now,int pre){ if(cur > m) return ; if(cur == m){ st[cnt][0] = pre; st[cnt][1] = now; cnt ++; return ; } dfs(cur + 2,((now<<2)|3),((pre<<2)|3));//当前行横放为11,那么上一行填11 dfs(cur + 1,((now<<1)|1),(pre<<1));// 当前行竖放为1,那么上一行填0 dfs(cur + 1,(now<<1),((pre<<1)|1));// 如果上一行为1,那么当前行不放置为0}int main(){ while(scanf("%d%d",&n,&m) , n + m){ if(n < m) swap(n,m); cnt = 0; memset(st,0,sizeof(st)); dfs(0,0,0); memset(dp,0,sizeof(dp)); dp[0][(1<<m)-1] = 1; for(int i = 0;i < n;i++) for(int j = 0;j < cnt;j++) dp[i+1][st[j][1]] += dp[i][st[j][0]]; cout << dp[n][(1<<m)-1] << endl; }}
poj 2663 解题方法与上题一样,题意 用1*2 的矩阵填充3*n的矩阵有多少种方法
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;typedef long long LL;#define M 100int dp[50][M];int st[M*11][2];int n,m,cnt;void dfs(int cur,int now,int pre){ if(cur > m) return ; if(cur == m){ st[cnt][0] = pre; st[cnt][1] = now; cnt ++; return ; } dfs(cur + 2,((now<<2)|3),((pre<<2)|3));//当前行横放为11,那么上一行填11 dfs(cur + 1,((now<<1)|1),(pre<<1));// 当前行竖放为1,那么上一行填0 dfs(cur + 1,(now<<1),((pre<<1)|1));// 如果上一行为1,那么当前行不放置为0}int main(){// freopen("1.txt","w",stdout); while(scanf("%d",&n)){ if(n < 0) break;// if(!n) {cout << 0 << endl;continue;} m = 3; if(n < m) swap(n,m); cnt = 0; memset(st,0,sizeof(st)); dfs(0,0,0); memset(dp,0,sizeof(dp)); dp[0][(1<<m)-1] = 1; for(int i = 0;i < n;i++) for(int j = 0;j < cnt;j++) dp[i+1][st[j][1]] += dp[i][st[j][0]]; cout << dp[n][(1<<m)-1] << endl; }}
poj - 3420 题意 用1*2 的矩阵填充4*n的矩阵有多少种方法(n比较大,用矩阵快速幂解决)
递推公式为 f(n) = f(n-1) + 5 * f(n-2) + f(n-3) - f(n-4)
构造矩阵
1 5 1 -1
1 0 0 0
0 1 0 0
0 0 1 0
此题还有一种方法:http://blog.csdn.net/shiwei408/article/details/8821853
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;typedef long long LL;LL mod;int n;struct Z{ LL m[4][4];};Z q = { 1,5,1,-1, 1,0,0,0, 0,1,0,0, 0,0,1,0};Z y = { 1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1};Z operator * (Z a,Z b){ Z c; memset(c.m,0,sizeof(c.m)); for(int i = 0;i < 4;i++) for(int j = 0;j < 4;j++) for(int k = 0;k < 4;k++) c.m[i][j] = (c.m[i][j] + a.m[i][k] * b.m[k][j]) % mod; return c;}Z Pow(int x){ Z ret,p; ret = y,p = q; while(x){ if(x&1) ret = p*ret ; p = p * p; x >>= 1; } return ret;}int main(){ int a[] = {1,1,5,11,36}; while(cin >> n >> mod,n+mod){ if(n < 5){cout << (a[n]%mod) << endl;continue;} Z r = Pow(n - 4); LL ans = (r.m[0][0]*36 + r.m[0][1] * 11 + r.m[0][2]*5 + r.m[0][3]) % mod; ans = (ans + mod) % mod; cout << ans << endl; }}
点头1033 骨牌覆盖V2 (状态压缩+矩阵乘法)
题意:同上 2<=n <= 10^9 && 2 <= m <= 5;
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;typedef long long LL;const LL mod = 1000000007;#define M 1<<5+1LL st[M][M];int n,m,cnt;struct Z{ LL m[32][32]; Z(){memset(m,0,sizeof(m));} void init(){ for(int i = 0;i < cnt;i++) m[i][i] = 1; }};void dfs(int cur,int now,int pre){ if(cur > m) return ; if(cur == m){ st[pre][now] = 1; return ; } dfs(cur + 2,((now<<2)|3),((pre<<2)|3));//当前行横放为11,那么上一行填11 dfs(cur + 1,((now<<1)|1),(pre<<1));// 当前行竖放为1,那么上一行填0 dfs(cur + 1,(now<<1),((pre<<1)|1));// 如果上一行为1,那么当前行不放置为0}Z operator * (Z a,Z b){ Z c; for(int i = 0;i < cnt ;i++) for(int k = 0;k < cnt ;k++) if(a.m[i][k]) for(int j = 0;j < cnt ;j++) c.m[i][j] = (c.m[i][j] + a.m[i][k] * b.m[k][j]) % mod; return c;}Z pow(int n,Z a){ Z ret ;ret.init(); while(n){ if(n&1) ret = ret * a; a = a * a; n >>= 1; } return ret;}int main(){ while(~scanf("%d%d",&n,&m)){ if(n < m) swap(n,m); memset(st,0,sizeof(st)); dfs(0,0,0); cnt = 1 << m; Z s; for(int i = 0;i < cnt;i++) for(int j = 0;j < cnt;j++) s.m[i][j] = st[i][j]; s = pow(n,s); printf("%lld\n",s.m[cnt-1][cnt-1]); } return 0;}
0 0
- poj 2411 && 2663 && 3420 && 点头1033
- 点头OJ 1033 . 骨牌覆盖 V2 ( 状态压缩 + 矩阵快速幂 )
- 点头 距离之和最小 V2
- 51nod点头网-1135 原根
- POJ 2411 + POJ 2663 + POJ 3420 小方格填充之多米诺骨牌系列(状压DP)
- 一到晚上12点头就晕了
- 困扰我多年的印度人点头摇头问题
- Windows主管离职内幕:盖茨点头 人缘太差
- 51nod点头网-1136 欧拉函数
- 51nod点头网-1240 莫比乌斯函数
- 51Nod点头网—1256 乘法逆元
- 51Nod点头网—1080 两个数的平方和
- 51Nod点头网-1014 X^2 Mod P
- 51Nod-点头网-1035 最长的循环节
- 微软262亿美元收购Linkedin,欧盟终于点头了
- 100道动态规划——31 POJ 2411 && POJ 2663 && POJ 3420 状态压缩 矩阵快速幂
- 51nod点头网-1284 2,3,5,7的倍数
- 51nod点头网-1181 质数中的质数(质数筛法)
- 如何查看CentOS版本
- apache 加载 php
- Cocos2d-x对JNI操作的封装:JniHelper类详解
- Ural1055(素数打表+分解质因数)
- 执行存储过程 存储空间不足,无法完成此操作
- poj 2411 && 2663 && 3420 && 点头1033
- 【转载】JAVA的文件操作
- 紫外线消毒器:飞利浦紫外线消毒器消毒设备的特点
- wget 命令用法详解
- 一次成功移植recovery过程
- 2014牡丹江 现场赛 F zoj 3824 Fiber-optic Network
- #Android笔记#popupwindow淡入淡出动画效果的研究
- des加密算法
- hdu 3966 Aragorn's Story(树链剖分+树状数组)