UVa上未解決的題目

來自《挑戰編程》和《算法競賽入門經典(第2版)》

Programming Challenges

習題1.6.3 10137 TheTrip

  • 因爲這道題的測試用例有錯誤,詳見這裏3樓的評論
  • 浮點數的題目我一向沒有好感

習題4.6.3 10037 Bridge

  • 網上給出了很多貪心的解法,還有爲數不多的動態規劃解法,但是我沒想明白

習題5.9.3 701 The Archeologists’ Dilemma

  • 如果嘗試枚舉E的話那麼很快程序就超時了
  • 雖然我也感覺不應該暴力枚舉求解,應該用對數,但是沒想出來那個不等式是怎麼來的(N * 10^K < 2^X < (N + 1) * 10^K)。

習題6.6.2 10213 How Many Pieces of Land ?

  • 想了好久,還是去網上查了一下,可以直接根據平面歐拉公式(F = E - V + 2)來算,因此這道題中區域總數爲1 + C(n, 2) + C(n, 4)
  • 需要使用大數運算
  • 我感覺面試題不會有這種東西吧?

習題6.6.4 10157 Expressions

  • 根據書上關於Catalan數的提示,可以得到遞推公式爲:
    S(n ,d) = sum(S(i, j) * S(n - 2 - i, d)(0 <= i <= n - 2, 0 <= j <= d - 2))
    + sum(S(i, d - 1) * S(n - 2 - i, j)(0 <= i <= n - 2, 0 <= j <= d))
  • 根據第一個括號閉合的位置將表達式分成兩部分,左邊被括起來的表達式深度分成兩部分來考慮:長度從0變化到n - 2,深度從0變化到d - 2,這樣被括起來後最大深度爲d - 1,所以右邊未被括起來的部分深度必須爲d,長度爲n - 2 - i;長度從0變化到n - 2,深度爲d - 1,這樣被括起來後深度爲d,所以右邊深度的變化範圍從0d。這樣每計算一項需要2重循環,計算所有的就需要4重循環
  • 通過觀察遞推公式,可以將部分項合併,第一項的S(i, j)j的範圍是0 <= j <= d - 2,而第二項中正好有S(i, d - 1),這樣合併後就可以得到:
    S(n, d) = sum(S(i, j) * S(n - 2 - i, d)(0 <= i <= n - 2, 0 <= j <= d - 1))
    + sum(S(i, d - 1) * S(n - 2 - i, j)(0 <= i <= n - 2, 0 <= j <= d - 1))
  • 因爲j只出現在乘積項的一側,而i出現在乘積項的兩側,所以可以對j進行優化,記T(i, d - 1) = sum(i, j)(0 <= j <= d - 1),表示長度爲i,深度不超過d - 1的表達式的個數,這樣遞推公式就又變成了:
    S(n , d) = sum(T(i, d - 1) * S(n - 2 - i, d)(0 <= i <= n - 2))
    + sum(S(i, d - 1) * T(n - 2 - i, d - 1)(0 <= i <= n - 2))
  • 然後根據剛纔對T的定義,將S代換爲T,可得:
    S(n, d) = sum(T(i, d - 1) * (T(n - 2 - i, d) - T(n - 2 - i, d - 1)))(0 <= i <= n - 2)
    + sum((T(i, d - 1) - T(i, d - 2)) * T(n - 2 - i, d - 1))(0 <= i <= n - 2)
    = sum(T(i, d - 1) * T(n - 2 - i, d) - T(i, d - 2) * T(n - 2 - i, d - 1))
  • 第一項表示長度爲i、深度不超過d - 1每一項用括號括起來後和長度爲n - 2 - i、深度不超過d進行組合,最後可得長度爲n,深度不超過d的表達式數量,就是剛剛定義的T(n, d),後邊一項正好爲T(n, d - 1)
  • 廢了一大圈勁,終於從樸素的想法推到正確的解題方法了。😦

習題6.6.5 10247 Complete Tree Labeling

  • 開始的時候一直思考如何從二層的二叉堆遞推三層的二叉堆,然後從二叉堆怎麼遞推三叉堆,但是發現一種固定編號的二層二叉堆,變成三層的過程中會破壞二層的編號,所以從具體的某一種編號方式應該是無法遞推
  • 看了一下網上的答案,如果不考慮二層的排列具體用了哪幾個數字,只考慮用可以得到多少種二層的排列,那麼在變成三層的時候,根一定是最小的1,然後從把剩下的數字平均分成k份,每一叉用一份,再用乘法原理進行計算

習題6.6.6 10254 The Priest Mathematician

  • 這明明是一個遞推題,公式也很好寫,f(n) = min(f(k) + 2^(n - k) - 1)(0 <= k < n),但是故意把數值搞大了,然後高精度計算也會超時
  • 其實它的一階差分序列是有規律的,我佛了 😦

習題7.6.8 10089 Repackaging

  • 這題不能枚舉,整數規劃使用割平面好像有解法,但是也不能直接套用,看網上說用凸包,這是個啥?

習題8.6.8 10270 Bigger Square Please…

  • 這道題看起來就賊難
  • 搜索肯定是能解的。首先要把N ^ 2表示爲小於N的數的平方和,然後根據這種表示方式,再嘗試進行覆蓋,最終取數量最小的那個
  • 根據書上的提示,深搜可以先取大的,或者是否可以用遞推來解決?我也不知道
  • 第二層深搜優先放置大的,大的本身位置就少,這樣或許可以剪枝?

習題10.5.7 10249 The Grand Dinner

  • 貪心或者最大流可解

習題10.5.8 10092 The Problem With the Problem Setter

  • 運籌學中的分配問題,或者稱爲指派問題,我記得郭強老師的《運籌學原理與算法》中給出了使用類似Floyd算法的求解方法
  • 該算法爲郭老師研究發明,可惜的是沒什麼人知道

算法競賽入門經典(第2版)

習題3-12 10189 Floating-Point Numbers

  • 同樣是浮點數的題目

例題5-2 101 The Blocks Problem

  • 一道根據題意模擬的題目,寫起來可能會很複雜

例題5-10 207 PGA Tour Prize Money
例題5-11 814 The Letter Carrier’s Rounds

  • 兩道根據題意模擬的題目
  • 看起來簡單,可能會有坑和難調的bug
  • 輸出格式複雜

習題5-12 221 Urban Elevations

  • 浮點數的簡單題目,但是還是先跳過
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章