想法:
這題與UVa 11997一樣,差別只在於UVa那題是K行K個數字,這題是M行N個數字,詳細過程我寫在UVa 11997 K Smallest Sums。
2014年3月7日 星期五
UVa 11997 K Smallest Sums
題意:
有K行,每行有K個數字,從每行裡面各選出1個數字並加起來共有K^K種組合的和,輸出最小的K個和。
想法:
我們可以先將第一行和第二行求出前K小的和,因此兩行數字就變成了一行數字,這一行數字再和第三行求出前K小的和,兩行又合併成一行,一直重複將兩行合併成一行,最後就是答案。
因此現在關鍵是如何有效率求出兩行的數字前K個最小的和,如果暴力解的話為O(K^2),很可能會TLE,用priority queue來解這題只要O(K),過程如下:
*假設第一行數字陣列為L1,第二行數字陣列為L2,
*要丟進priority queue(底下簡稱PQ)裡的structure裡面含有兩個元素,第一個為val: 表示L1某個數+L2某個數的和,第二個為pos: 表示L2某個數在L2的位置(index)。
有K行,每行有K個數字,從每行裡面各選出1個數字並加起來共有K^K種組合的和,輸出最小的K個和。
想法:
我們可以先將第一行和第二行求出前K小的和,因此兩行數字就變成了一行數字,這一行數字再和第三行求出前K小的和,兩行又合併成一行,一直重複將兩行合併成一行,最後就是答案。
因此現在關鍵是如何有效率求出兩行的數字前K個最小的和,如果暴力解的話為O(K^2),很可能會TLE,用priority queue來解這題只要O(K),過程如下:
*假設第一行數字陣列為L1,第二行數字陣列為L2,
*要丟進priority queue(底下簡稱PQ)裡的structure裡面含有兩個元素,第一個為val: 表示L1某個數+L2某個數的和,第二個為pos: 表示L2某個數在L2的位置(index)。
- 將L1遞增排序
- 將L2遞增排序。
- 然後把L1裡面每個數字和L2[0]加起來,val=L1[i]+L2[0]和pos=0放到PQ裡面。
- L1的數字就不會用到了
- 之後每次從PQ裡面拿出第一個(最小的val),將這個val放入L1(覆蓋以重複利用L1),然後將這個val=(val-L2[pos]+L2[pos+1])和pos=pos+1丟回PQ裡
- 重複步驟5 K次,L1裡面就有K個數字,表示這兩行已經合併成功
- 讀入下一個L2,並重複步驟2~7,直到將K行合併成一行
- 輸出L1
用這方法將兩行合併成一行的時候,只要做K次即可,因為我們已經將L1都丟進PQ裡面,然後每次都選最小和出來,並同時把可能的答案丟入PQ。
2014年3月2日 星期日
POJ 2431 Expedition
題意:
一群牛從起點要出發到城鎮(目的地)距離共L單位,每走一單位同時消耗一單位的油,一開始油箱有P單位的油量,路途中會經過幾個加油站,每個加油站會給兩個數字,1.距離城鎮多少單位,2.這個加油站能加多少油,本題問到目的最少要到幾個加油站加油,如果不可能到達目的地則輸出-1。
想法:
因為所有地點都在同一直線上,所以都會經過每個加油站,只是看要不要停下來加油而已。所以我們就盡可能往前走,把每個路過加油站的該站的加油量放到priority queue裡面,然後直到走到途中沒油了,就從priority queue裡面拿出第一個(最大的加油量)加到自己的油箱,因為既然要加油,就要一次加最多的油,一直反覆這個動作直到終點。
一群牛從起點要出發到城鎮(目的地)距離共L單位,每走一單位同時消耗一單位的油,一開始油箱有P單位的油量,路途中會經過幾個加油站,每個加油站會給兩個數字,1.距離城鎮多少單位,2.這個加油站能加多少油,本題問到目的最少要到幾個加油站加油,如果不可能到達目的地則輸出-1。
想法:
因為所有地點都在同一直線上,所以都會經過每個加油站,只是看要不要停下來加油而已。所以我們就盡可能往前走,把每個路過加油站的該站的加油量放到priority queue裡面,然後直到走到途中沒油了,就從priority queue裡面拿出第一個(最大的加油量)加到自己的油箱,因為既然要加油,就要一次加最多的油,一直反覆這個動作直到終點。
訂閱:
文章 (Atom)