如果遇到這種解方程的題目,想把它每個未知數寫出公式可不容易,而在不知道解的資料範圍的時候,二分列舉什麼的和沒做沒區別,所以這裡引入了高斯消元對此進行解答。
高斯消元簡直就是為計算機量身打造的解n元一次方程組的利器,雖然在演算法競賽中並不會考像加減消元這種容易的題目,但是這作為它的基礎,還是需要討論一下的。
1、基礎概念
高斯消元是指,用第i個式子將它下方的n-i個式子的第i個未知數係數通過加減消元法變為零,然後反過來求解所有未知數的過程。
2、加減消元
為了方便描述,我們將每個式子按照同乙個未知數對齊的原則進行排列(若有的方程中有的未知數不存在,則係數用0表示,即空位),並且把未知數都放在左邊,常數放在右邊,為了簡化寫法,這裡用行列式表示每個方程中各個未知數的係數,圖中第i行第j列表示的是第i個方程第j個未知數的係數,第n+1列表示的是常數項(為了方便描述,假定所有的係數都不為零,為零的情況稍候討論),如下描述:
a[1][1] a[1][2] a[1][3] ... a[1][n] | c[1]
a[2][1] a[2][2] a[2][3] ... a[2][n] | c[2]
a[n][1] a[n][2] a[n][3] ... a[n][n] | c[n]
然後進行第一步操作:
a[1][1] a[1][2] a[1][3] ... a[1][n] | c[1]
0 a[2][2]*a[1][1]-a[1][2]*a[2][1] a[2][3]*a[1][1]-a[1][3]*a[2][1] ... | c[2]*a[1][1]-c[1]*a[2][1]
0 a[3][2]*a[1][1]-a[1][2]*a[3][1] a[3][3]*a[1][1]-a[1][3]*a[3][1] ... | c[3]*a[1][1]-c[1]*a[3][1]
上圖很清晰得表達了我們操作的意義,經過第一步操作,除了第乙個方程之外,所有方程第一項的係數都變成了0,更新每個方程的係數。而接下來的第二步則使得除了第一,二個方程之外的第二項係數變成了0,如此反覆,直至第n-1步之後,你會驚奇的發現,第n個方程中只有第n個未知數了!而那就是乙個一元一次方程!很容易得到了x[n]的值,接下來將x[n]n代入上面的每乙個方程,並將其與常數項合併,你又會發現,x[n-1]也可以通過第n-1個方程求解了!如此逆推而上,就得到了所有未知數的值!
3、演算法分析
通過上述的解法,很容易就可以敲出**,但是還有要注意的地方:
no.1 無解的情況:
當有乙個方程所有係數都為0而常數項不為0時,方程組是無解的;
no.2 有係數為零的情況:
在處理資料的過程中,可能遇到某個係數為零,這時是可以直接跳過的,因為我們在這一步上的目的即使跳過它了也能完成。
下面是詳細**:
#includeconstint maxn = 100 + 10; //
假設要求解的方程組最多為100元
double dat[maxn][maxn],ans[maxn]; //
整數除法可能會出問題(萬一不能整除呢?)
intn;
bool rt = 1; //
記錄是否有解
void init()
}}void work() }}
if(dat[n+1][n+1]) rt = 0; //
若所有係數都為零而等式右邊不為零時,方程組無解
}void
solv()
}}void prnt()
for(int i = 1;i <= n;++i)
else
printf("\n
");}
}int
main()
高斯消元法(一) 簡介
高斯消去法主要用於求解線性方程組的解,但由於演算法相對複雜,因此常用於低階稠密方程組 個人理解稠密即為方程組中的係數項為0的個數少,也就是係數矩陣a零元素的個數少,反之則為稀疏方程組 如已知乙個n元n次的方程組,代數形式即可寫成如下形式 我們可以將其轉化為矩陣形式 ax b 其中a為係數矩陣,如下 ...
hihoCoder 1195 高斯消元 一
時間限制 10000ms 單點時限 1000ms 記憶體限制 256mb 描述小ho 喂不得了啦,那邊便利店的薯片半價了 小hi 啥?小ho 那邊的便利店在打折 啊。小hi 走走走,趕緊去看看 v 於是小hi和小ho來到了便利店。老闆為了 推出了組合包的形式,將不同數量的各類商品打包成乙個組合,顧客...
hihoCoder 1195 高斯消元 一
時間限制 10000ms 單點時限 1000ms 記憶體限制 256mb 描述小ho 喂不得了啦,那邊便利店的薯片半價了 小hi 啥?小ho 那邊的便利店在打折 啊。小hi 走走走,趕緊去看看 v 於是小hi和小ho來到了便利店。老闆為了 推出了組合包的形式,將不同數量的各類商品打包成乙個組合,顧客...