學習筆記----高斯消元(二)

畫船聽雨發表於2014-07-30

今年多校比賽第一場遇到了高斯消元,不會,就學習了一下啊。

先說一下學習的部落格:

http://www.cppblog.com/menjitianya/archive/2014/06/08/207226.html

http://www.cnblogs.com/kuangbin/category/409938.html

http://hi.baidu.com/czyuan_acm/item/dce4e6f8a8c45f13d7ff8cda

高斯消元主要是解決線性方程組的係數。

演算法核心思想:
        對於n個方程,m個未知數的方程組,消元的具體步驟如下:
       1、列舉第i (0 <= i < n) 行,初始化列為col = 0,每次從[i, n)行中找到第col列中元素絕對值最大的行和第i行進行交換(找到最大的行是為了在消元的時候把浮點數的誤差降到最小);
           a) 如果第col列的元素全為0,放棄這一列的處理,col+1,i不變,轉1);
           b) 否則,對於所有的行j (i < j < n),如果a[j][col]不為0,則需要進行消元,以期第i行以下的第col列的所有元素都消為0(這一步就是線性代數中所說的初等行變換,具體的步驟就是將第j行的所有元素減去第i行的所有元素乘上一個係數,這個係數即a[j][col] / a[i][col])。
       2、重複步驟1) 直到n個方程列舉完畢或者列col == m。
       3、判斷解的情況:
           a) 如果出現某一行,係數矩陣全為0,增廣矩陣不全為0,則無解(即出現[0 0 0 0 0 b],其中b不等於0的情況);
           b) 如果是嚴格上三角,則表明有唯一解;
           c) 如果增廣矩陣有k (k > 0)行全為0,那麼表明有k個變數可以任意取值,這幾個變數即自由變數;對於這種情況,一般解的範圍是給定的,令解的取值有T個,自由變數有V個,那麼解的個數就是 TV。

有的時候需要求最小的解,那麼就要狀壓列舉變元,求最小的解。

下面總結一下,這幾天做的題目:

HDU 4870 Rating(概率dp+高斯消元)

多校聯合的題目,通過概率推公式之後得到一個矩陣然後,用高斯消元接出x[0],這是高斯消元解實數的題目在進行行變換的時候與整數不同,直接去掉倍數就行。還有就是高斯消元需要的精度比較高大約是1e-10左右。


 

POJ 2947 Widget Factory(取模的高斯消元)


高斯消元解決取模問題的題目,應為最後一列都進行了取模的操作,所以當你在解的時候,如果取餘不等於0,需要加上x個mod,使得可以整除。


POJ 2065 SETI(高斯消元)

給你一些素數,每次對不同的數取餘,其實就是看懂題意,然後一個解決取模問題就行了啊。


POJ 1222 EXTENDED LIGHTS OUT(高斯消元,開關問題)

開關問題,每個點可以和其他相鄰的點有關係,如果改動一個點會有其他的點跟著受影響。如果一個點和其他的點有關係他們之間的關係就是1,否則是0。終態是已經給你的,你通過建立的關係就會列出來一個30*30的方程組出來。然後解這個方程組,所得的解就是,開關需不需要動。這裡因為開關的狀態是隻有兩種0,1所以可以按照對2取餘來解決。


POJ 1166 The Clocks(高斯消元)

神奇的題目,有很多人暴力搞的。我是建完關係之後用的高斯消元,把找最大的交換改成找任意的交換,就過了。不知道為什麼。而且有一些人說這題是模4,不是素數會出現問題。


POJ 1830 開關問題(高斯消元)

題目就叫開關問題、、、根據題目建立關係,找出解的個數,如果會有多種解返回個數。無解返回-1.因為每自由元解可以取或不取兩種情況,所以共有2^k種解。


POJ 1753 Flip Game(列舉變元的高斯消元)

這道題目資料很小所以可以dfs,用高斯消元反而麻煩一些了啊。但是可以練習一下高斯消元。這道題目就是類似於開關問題,每個旗子影響其他的旗子。而且終態有兩種,全為0,或者全為1。但是這道題目要求輸出最少的操作,所以當遇到有多種解的時候你需要列舉一下每個變元,然後求出操作的次數,儲存一個操作次數最少的,輸出來。


 

POJ 3185 The Water Bowls(高斯消元,列舉變元)


和1753很像都需要列舉變元,解出來最少的操作次數。


HDU 3976 Electric resistance(高斯消元)

這道題目,上來就是電路圖啊,得根據KFC(節點電壓法)不是肯德基!通過節點的電流列出關係。然後解出來x[n-1]的結果。


SGU 200. Cracking RSA(高斯消元+高精度)

給出m個整數,因子全部存在於前t個素數。問有多少個子集,他們的乘積是平方數。這道題目感覺不簡單,而且思想很好,是個好題啊,標記一下,以後還得多看。

是的乘積是個平方數,那麼每一個質數的指數次對2取餘都是0。所以我們讓最後一列為0,然後解方程組,返回變元的個數所以解的組合有2^k - 1。去掉空集。


SGU 275. To xor or not to xor(高斯消元)


好題啊,而且不簡單啊。。。不好理解,看了老長時間才理解一點,智商不夠啊、、、

給你n個數字,讓你從n個數中,選擇一些數,使得異或最大。

要從最高位進行解,我們想要每一位儘可能的為1。所以判斷為1是否有解,如果有的話就加上。還有就是一點一點的解方程第一次解第0行,第二次解0~1行,依此類推、、、這樣可以使得最高位儘量的為1。


還得繼續做題,未完待續。。。。

相關文章