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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ACM竞赛学习整理--矩阵运算

發布時間:2025/3/15 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ACM竞赛学习整理--矩阵运算 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

ACM競賽學習整理–矩陣運算

了解矩陣類

【任務】

實現矩陣的基本變換

【接口】

結構體:Matrix

成員變量:

int n,m 矩陣大小

int a[][] 矩陣內容

重載運算符: +、-、x

成員函數:void clear() 清空矩陣

【代碼】

const int MAXN = 1010; const int MAXM = 1010;struct Matrix{int n,m;int a[MAXN][MAXM];void clear(){n=m=0;memset(a,0,sizeof(a));} }Matrix operator +(const Matrix &b) const{Matrix tmp;tmp.n = n;tmp.m = m;for(int i = 0;i<n;++i)for(int j=0;j<m;++j)tmp.a[i][j] = a[i][j] + b.a[i][j];return tmp; }Matrix operator -(const Matrix &b) const{Matrix tmp;tmp.n = n;tmp.m = m;for(int i = 0;i<n;++i)for(int j=0;j<m;++j)tmp.a[i][j] = a[i][j] - b.a[i][j];return tmp; }Matrix operator *(const Matrix &b) const{Matrix tmp;tmp.clear();tmp.n = n;tmp.m =b.m;for(int i = 0;i<n;++i)for(int j=0;j<b.m;++j)for(int k=0;k<m;++k)tmp.a[i][j] += a[i][k] * b.a[k][j];return tmp; }

【擴展】

關于矩陣加速數列遞推:

給定一個遞推數列

f[i]=a1?f[i?1]+a2?f[i?2]…ak?f[i?k] ,

我們普通計算的話肯定是逐個計算,復雜度較大。

我們可以用矩陣表示:

為了遞推出f[n] , 我們需要找到一個系數矩陣 A 使得:

就可以這樣計算:

A矩陣可以這樣構造:

至此,我們可以愉快地用矩陣加速遞推數列了。

參考來源:https://www.cnblogs.com/alecli/p/10004417.html

【應用】

poj 2663詳解

Description
In how many ways can you tile a 3xn rectangle with 2x1 dominoes?
Here is a sample tiling of a 3x12 rectangle.

Input
Input consists of several test cases followed by a line containing -1. Each test case is a line containing an integer 0 <= n <= 30.

Output
For each test case, output one integer number giving the number of possible tilings.

Sample Input
2
8
12
-1

Sample Output
3
153
2131

分析題目,這是一個遞推關系求解題,并且很容易發現當n為奇數時,無法找到滿足題意的鋪法,以下僅考慮n為偶數的情況。

思路:
這里先定義兩個概念:獨立單位和非獨立單位。獨立單位即不可縱向切割的矩形塊, 非獨立單位即可縱向切割的矩形塊。

我們先來試試幾種簡單情況。當n = 2時,有3種鋪法,如下圖。

當n=4時。組合分為兩種情況:一種是兩個n=2的獨立單位組合,另一種是一個n=0的獨立單位組合上一個n=4的獨立單位。分別如下圖。

兩個n=2的獨立單位組合,比較簡單,鋪法為3x3。一個n=0的獨立單位組合上一個n=4的獨立單位,通過畫圖可以判斷,只有兩種情況,分別為:

那么n=4的總鋪法數就容易確定了,為 3xa[2]+2xa[0] (這里a[0]=1,至于為什么等于1,請讀者自己體會)

接下來考慮n= 6,這時有三種組合情況,分別為:

  • 一個n=4的獨立單位連接上一個n=2的獨立單位;
  • 一個n=2的獨立單位連接上一個n=4的獨立單位;
  • 一個n=0的獨立單位連接上一個n=6的獨立單位。
    組合1:鋪法為a[4]x3;
    組合2:鋪法為a[2]x2;
    組合3:鋪法為a[0]x2;
    故n=6時的總鋪法數為:a[4]x3+a[2]x2+a[0]x2。
    (有人可能會問為什么要乘以2,這里請讀者自行畫圖求解…)
  • 當n更大時,以此類推。
    所以最后我們得出a[n] = 3xa[n-2]+2x(a[n-4]+a[n-6] +…+a[0]),再運用高中所學數列知識,化簡得:a[n] = 4a[n-2] - a[n-4];
    代碼整理如下:

    #include<iostream> #include<string.h> using namespace std; const int MAXN=10; const int MAXM=10;const long long mod = 1000007; int r; //矩陣類模板 struct Matrix{int n,m;int a[MAXN][MAXM];void clear(){n=m=0;memset(a,0,sizeof(a));}Matrix operator +(const Matrix &b) const {Matrix tmp;tmp.n=n;tmp.m=m;for (int i=0;i<n;++i)for(int j=0;j<m;++j)tmp.a[i][j]=a[i][j]+b.a[i][j];return tmp;}Matrix operator -(const Matrix &b)const{Matrix tmp;tmp.n=n;tmp.m=m;for (int i=0;i<n;++i)for(int j=0;j<m;++j)tmp.a[i][j]=a[i][j]-b.a[i][j];return tmp;}Matrix operator * (const Matrix &b) const{Matrix tmp;tmp.clear();tmp.n=n;tmp.m=b.m;for (int i=0;i<n;++i)for(int j=0;j<b.m;++j)for (int k=0;k<m;++k){tmp.a[i][j]+=a[i][k]*b.a[k][j];tmp.a[i][j]%=mod;}return tmp;}Matrix get(int x){//冪運算Matrix E;E.clear();E.n=E.m=n;for(int i=0;i<n;++i)E.a[i][i]=1;if(x==0) return E;else if(x==1) return *this;Matrix tmp=get(x/2);tmp=tmp*tmp;if(x%2) tmp=tmp*(*this);return tmp;} }; //矩陣模板結束int main(){while(cin>>r){if(r==0) break;int a[]= {1,0,3,0};if(r<=3){cout<<a[r]%mod<<endl;continue;}Matrix A;A.clear();A.n=A.m=4;A.a[0][1]=A.a[1][2]=A.a[2][3]=1;A.a[3][0]=-1;//A.a[3][1]=1;A.a[3][2]=4;//A.a[3][3]=1;A=A.get(r-3);Matrix M;M.clear();M.n=4;M.m=1;M.a[0][0]=1;M.a[2][0]=3;M.a[3][0]=0;M=A*M;cout<<(M.a[3][0]+mod)%mod<<endl;}return 0; }

    ps: ACM國際大學生程序設計與競賽-算法基礎(俞勇主編)里有介紹矩陣的實現,剛好手上有個項目要用到矩陣的操作, 一開始想用Eigen 庫來實現矩陣的操作,后來想想干脆還是C去實現吧。下午空閑一會了,找了一個ACM的例題來做做。于是就拙了一篇,請大家多指正。

    總結

    以上是生活随笔為你收集整理的ACM竞赛学习整理--矩阵运算的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。