poj 2411 2663 3420 点头1033
poj 2411?http://poj.org/problem?id=2411 ?? ? ??
題意:讓你用1*2的矩陣去填滿(mǎn)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));//當(dāng)前行橫放為11,那么上一行填11dfs(cur + 1,((now<<1)|1),(pre<<1));// 當(dāng)前行豎放為1,那么上一行填0dfs(cur + 1,(now<<1),((pre<<1)|1));// 如果上一行為1,那么當(dāng)前行不放置為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));//當(dāng)前行橫放為11,那么上一行填11dfs(cur + 1,((now<<1)|1),(pre<<1));// 當(dāng)前行豎放為1,那么上一行填0dfs(cur + 1,(now<<1),((pre<<1)|1));// 如果上一行為1,那么當(dāng)前行不放置為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)
構(gòu)造矩陣 ? ??
? ?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;} }點(diǎn)頭1033 骨牌覆蓋V2? ? ? ? ?(狀態(tài)壓縮+矩陣乘法)
題意:同上 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));//當(dāng)前行橫放為11,那么上一行填11dfs(cur + 1,((now<<1)|1),(pre<<1));// 當(dāng)前行豎放為1,那么上一行填0dfs(cur + 1,(now<<1),((pre<<1)|1));// 如果上一行為1,那么當(dāng)前行不放置為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; }
總結(jié)
以上是生活随笔為你收集整理的poj 2411 2663 3420 点头1033的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: HDU 3001 Travelling
- 下一篇: hdu- 5015 233 Matrix