hdu4965 巧用矩阵乘法结合律
生活随笔
收集整理的這篇文章主要介紹了
hdu4965 巧用矩阵乘法结合律
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
題意:
? ? ?給兩個(gè)矩陣,n*m的矩陣A,和m*n的矩陣B,
求(A*B)^(n*n)其中 m<=6,n<=1000。
思路:
? ? ? 一開始直接模擬,寫了個(gè)矩陣快速冪,超時(shí)了,因?yàn)锳*B后得到的是1000*1000的矩陣,做乘法直接超時(shí)了,后來寫了個(gè)這樣的
? ? (A*B)^(n*n) = (A*B)*(A*B)*(A*B)...
? ? ? ? ? ? ? ? ? ? ? ?= A * (B*A)*(B*A)*(B*A)...*B
? ? ?給兩個(gè)矩陣,n*m的矩陣A,和m*n的矩陣B,
求(A*B)^(n*n)其中 m<=6,n<=1000。
思路:
? ? ? 一開始直接模擬,寫了個(gè)矩陣快速冪,超時(shí)了,因?yàn)锳*B后得到的是1000*1000的矩陣,做乘法直接超時(shí)了,后來寫了個(gè)這樣的
? ? (A*B)^(n*n) = (A*B)*(A*B)*(A*B)...
? ? ? ? ? ? ? ? ? ? ? ?= A * (B*A)*(B*A)*(B*A)...*B
矩陣雖然沒有交換律但是有結(jié)合律,我們直接先B*A(得到的是一個(gè)最大6*6的矩陣)然后快速冪,然后再A * BA^(n*n-1) * B這樣就行了,然后又超時(shí)了,算了很多次,感覺不可能超時(shí),但還是超時(shí)了,原因就是我所有的矩陣用的都是mat[1002][1002]為了方便我都開結(jié)構(gòu)體了,結(jié)果各種超時(shí),最后沒辦法了,全都開數(shù)組,然后去模擬,A[1002][8],B[8][1002],BA[8][8]...,這樣就AC了,難道開大的數(shù)組也會浪費(fèi)很多時(shí)間?(這個(gè)地方頭一次碰到)。
#include<stdio.h> #include<string.h> typedef struct {int mat[8][8]; }AA;int A[1002][8] ,B[8][1002] ,C[1002][1002]; int nmm[1002][8];AA mat_matba(int n ,int m) {AA c;memset(c.mat ,0 ,sizeof(c.mat)); for(int k = 1 ;k <= n ;k ++)for(int i = 1 ;i <= m ;i ++)if(B[i][k])for(int j = 1 ;j <= m ;j ++)c.mat[i][j] = (c.mat[i][j] + B[i][k] * A[k][j])%6 ;return c; }AA mat_mat(AA a ,AA b ,int n) {AA c;memset(c.mat ,0 ,sizeof(c.mat));for(int k = 1 ;k <= n ;k ++)for(int i = 1 ;i <= n ;i ++)if(a.mat[i][k])for(int j = 1 ;j <= n ;j ++)c.mat[i][j] = (c.mat[i][j] + a.mat[i][k] * b.mat[k][j]) % 6;return c; }AA quick_mat(AA a ,int b ,int n) {AA c;memset(c.mat ,0 ,sizeof(c.mat));for(int i = 1 ;i <= n ;i ++)c.mat[i][i] = 1;while(b){if(b&1) c = mat_mat(c ,a ,n);a = mat_mat(a ,a ,n);b >>= 1;}return c; }void mat_matnmm(AA mm ,int n ,int m) {memset(nmm ,0 ,sizeof(nmm));for(int k = 1 ;k <= m ;k ++)for(int i = 1 ;i <= n ;i ++)if(A[i][k]) for(int j = 1 ;j <= m ;j ++)nmm[i][j] = (nmm[i][j] + A[i][k] * mm.mat[k][j]) % 6; }void mat_matnmmn(int n ,int m) {memset(C ,0 ,sizeof(C));for(int k = 1 ;k <= m ;k ++)for(int i = 1 ;i <= n ;i ++)for(int j = 1 ;j <= n ;j ++)C[i][j] = (C[i][j] + nmm[i][k] * B[k][j]) % 6; } int main () {int n ,m ,i ,j;while(~scanf("%d %d" ,&n ,&m) && n + m){for(i = 1 ;i <= n ;i ++)for(j = 1 ;j <= m ;j ++)scanf("%d" ,&A[i][j]);for(i = 1 ;i <= m ;i ++)for(j = 1 ;j <= n ;j ++)scanf("%d" ,&B[i][j]);AA c = mat_matba(n ,m);AA ban = quick_mat(c ,n*n-1 ,m);mat_matnmm(ban ,n ,m);mat_matnmmn(n ,m);int sum = 0;for(i = 1 ;i <= n ;i ++)for(j = 1 ;j <= n ;j ++)sum += C[i][j];printf("%d\n" ,sum);}return 0; }
總結(jié)
以上是生活随笔為你收集整理的hdu4965 巧用矩阵乘法结合律的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hdu3117 斐波那契前后4位
- 下一篇: hdu4966 最小树形图(最少辅导花费