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,這時有三種組合情況,分別為:
組合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];
代碼整理如下:
ps: ACM國際大學生程序設計與競賽-算法基礎(俞勇主編)里有介紹矩陣的實現,剛好手上有個項目要用到矩陣的操作, 一開始想用Eigen 庫來實現矩陣的操作,后來想想干脆還是C去實現吧。下午空閑一會了,找了一個ACM的例題來做做。于是就拙了一篇,請大家多指正。
總結
以上是生活随笔為你收集整理的ACM竞赛学习整理--矩阵运算的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ACM竞赛学习整理开篇之01背包问题
- 下一篇: ACM竞赛学习整理--Gauss求解PO