【poj3734】矩阵乘法求解
?
【題意】
? ? ? 給N個方塊排成一列。現在要用紅、藍、綠、黃四種顏色的油漆給這些方塊染色。求染成紅色方塊和染成綠色方塊的個數同時為偶數的染色方案的個數,輸出對10007取余后的答案。(1<=n<=10^9)。
?
【分析】
? ? ? 看到這題的題目的第一想法是什么呢?我也不知道,因為還沒做就知道是一道用矩陣乘法完成遞推的題目了嘛!!
? ? ? 之前對矩陣乘法的理解不是很好,不知道可以同時推很多個元素的,于是腦子就卡了~~不寫那么多亂七八糟的想法了,直接寫題解吧。
? ? ? 當我們準備準備染第i個方塊的時候,前i-1個方塊已經染好顏色了。對于我們的目標顏色紅色和綠色,根據我們想要紅綠同時為偶的想法,我們可以把前i-1個方塊的染色分成3種情況:
? ? ? ? 1.紅色和綠色同時為偶數的方案數
? ? ? ? 2.紅色和綠色中一個偶數一個奇數的方案數
? ? ? ? 3.紅色和綠色同時為奇數的方案數
? ? 我們記前3種情況的方案數為ai-1,bi-1,ci-1。
? ? 我們最后需要的是an,但是我們需要a,b,c進行遞推。
? ? 根據以上想法,我們希望用ai-1,bi-1,ci-1推出ai,bi,ci。
? ? 那么,多一個格子染色方案有多少個,是很容易推出來的哦:
? ? ? ? ai=2*ai-1+bi-1;
? ? ? ? bi=2*ai-1+2*bi-1+2*ci-1;
? ? ? ? ci=bi-1+2*c-1;
? ? 根據這個遞推式,我們可以得到矩陣A:
| 2 | 1 | 0 |
| 2 | 2 | 2 |
| 0 | 1 | 2 |
?
? ?矩陣B為i=0的時候a,b,c的值:
| 1 |
| 0 |
| 0 |
?
? ? 然后用同樣的快速冪求矩陣乘法的方法求解。
?
? ? 代碼如下:
??
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #define Mod 10007 5 6 struct node 7 { 8 int v[5][5]; 9 int m,l; 10 }; 11 12 node get_mul(node a,node b) 13 { 14 node c; 15 c.m=a.m;c.l=b.l; 16 for(int i=1;i<=c.m;i++) 17 for(int j=1;j<=c.l;j++) 18 { 19 c.v[i][j]=0; 20 for(int k=1;k<=a.l;k++) 21 c.v[i][j]=(c.v[i][j]+a.v[i][k]*b.v[k][j])%Mod; 22 } 23 return c; 24 } 25 26 int main() 27 { 28 int T,n; 29 scanf("%d",&T); 30 while(T--) 31 { 32 scanf("%d",&n); 33 node a,b,c; 34 a.m=a.l=3;a.v[1][1]=2;a.v[1][2]=1;a.v[1][3]=0; 35 a.v[2][1]=a.v[2][2]=a.v[2][3]=2; 36 a.v[3][1]=0,a.v[3][2]=1,a.v[3][3]=2; 37 b.m=3,b.l=1,b.v[1][1]=1,b.v[2][1]=0,b.v[3][1]=0; 38 c.m=c.l=3;c.v[1][1]=c.v[2][2]=c.v[3][3]=1; 39 c.v[1][2]=c.v[1][3]=c.v[2][1]=c.v[2][3]=c.v[3][1]=c.v[3][2]=0; 40 while(n) 41 { 42 if(n&1) c=get_mul(c,a); 43 a=get_mul(a,a); 44 n>>=1; 45 } 46 c=get_mul(c,b); 47 printf("%d\n",c.v[1][1]); 48 } 49 return 0; 50 } poj3734? ? 有人能教我如何漂亮地打表么?
?
2015-09-19?10:57:49
?
轉載于:https://www.cnblogs.com/Konjakmoyu/p/4821101.html
總結
以上是生活随笔為你收集整理的【poj3734】矩阵乘法求解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hibernate Disabling
- 下一篇: 事务中SET XACT_ABORT各种用