日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

hdu4965 巧用矩阵乘法结合律

發(fā)布時(shí)間:2025/6/17 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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

矩陣雖然沒有交換律但是有結(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)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。