czl的知識點整理2 高斯消元

2021-08-09 13:27:00 字數 1906 閱讀 7040

xjoi 1822:civilization

高斯消元其實在小學初中解多元一次方程的時候已經接觸過了。其實,高斯消元就是建立在方程中加減消元和乘除消元之上的。只不過,高斯消元法把這兩種方法應用於矩陣之中,使得高斯消元的複雜度達到o(n³)(相比於真正的去解方程可是要快的多了,想一想你手解100000元一次方程需要多久就行了)。

然後就是高斯消元的實現了。首先,我們要把高斯消元的每乙個係數都加入到n*(n+1)的矩陣中(第n行第n+1列填的是這個方程的答案,但在最後要被我們轉化為第n元的解)。

首先,把他們的係數都加入乙個矩陣當中:

然後,我們要確定我們所期望的解決後的矩陣是怎樣的。這樣的矩陣無非兩種,一種是上三角矩陣,第i行的元素個數為n-i+1個,並且第i行的前i-1個元素都必須為0。然後從最後一行開始解方程,不斷地代入上一行的方程,知道解除答案。而另一種方法則是第i行只有第i個元素不為0,這樣可以直接解出每個數的解。然而前者實現較為簡單,所以我們今天就用前者。

然後開始我們的消元。首先先從第一列開始,先把該列中絕對值最大的元素所在的哪一行提至第一列(目的是為了提高資料的穩定性,數**算都是含捨入誤差的計算,選主元進行消去可以極大降低捨入誤差)。然後就想簡單的乘除加減消元一樣,把下面的每一列的值都消為0。

下面是第一步舉例:

最後是結果的矩陣:

現在只需要從下往上乙個乙個的解出每一元的解即可。最後得出的解為x=2,y=5,z=8。

然後該怎麼判斷方程是否有解呢?

只需要按下面的方法判斷即可:

① 無解

當方程中出現(0, 0, …, 0, a)的形式,且a != 0時,說明是無解的。

② 唯一解

條件是k = equ,即行階梯陣形成了嚴格的上三角陣。利用回代逐一求出解集。

③ 無窮解。

條件是k < equ,即不能形成嚴格的上三角形,自由變元的個數即為equ – k。

#include

using

namespace

std;

typedef

long

double ld;//這裡用了long double,是為了精度,但是xjoi原題需要用另一種方法來記錄消元時的數,有興趣可自己去試試

const

int maxn=205;

ld a[maxn][maxn];

char in[maxn];//由於xjoi好像不能讀long double,所以用了讀字串的方式

void guass(ld x[maxn][maxn],int n)

if(r!=i)for(int j=0;j<=n;j++)swap(x[r][j],x[i][j]);//找出絕對值最大的那一列並進行交換

for(int j=n;j>=i;j--)}}

for(int i=n-1;i>=0;i--)}}

guass(a,n);

double res;

for(int i=0;idouble)a[i][n];//硬生生轉回了double輸出

printf("%.0lf\n",res);}}

czl的知識點整理4 線段樹

首先對於線段樹,其實與其他各種樹都是一樣的,都有著樹形的結構。接下來讓我們考慮一些問題 給出乙個陣列,要求滿足下面的操作 給定三個值x,y,z,要求吧 x,y 區間的每個數都加上z。給定兩個值x,y,要求輸出 x,y 區間的最大值 or最小值or和 如果我們用暴力做這些問題,那麼對於操作 和 每次的...

czl的知識點整理5 單調佇列

既然在模板庫中發了單調佇列的板子,那麼就順便把單調佇列講一講吧。我不會說是在noip前一天攢一攢rp的 單調佇列和單調棧的方法差不多,而且可以算是不會線段樹的oier的福音了。所以單調棧也不會的同學也來學一學吧,反正操作也是差不多的。回歸正題 單調佇列的用途是維護乙個區間的最值的 是不是很像線段樹啊...

知識點 高斯消元 線性基

高斯消元 解 n 元一次方程組的通用方法,大部分時候用於解決沒有明顯轉移順序的dp。考慮將方程組列成乙個 n times n 1 的矩陣 a 然後依次列舉每乙個未知數 j 第 j 列 從上往下找到第乙個 i 滿足 i geq j,a neq 0 如果找不到則該方程組無解,退出。否則把第 i 行與第 ...