1. 程式人生 > 其它 >ACM - 動態規劃 - UVA437 The Tower of Babylon

ACM - 動態規劃 - UVA437 The Tower of Babylon

UVA437 The Tower of Babylon

題解

初始時給了 \(n\) 種長方體方塊,每種有無限個,對於每一個方塊,我們可以選擇一面作為底。然後用這些方塊儘可能高地堆疊成一個塔,要求只有一個方塊的底的兩條邊嚴格小於另一個方塊的底的兩條邊,這個方塊才能堆在另一個上面

問題的思考在於每種方塊有無限個,如果我們直接利用該條件問題會變得比較複雜。其實仔細考慮方塊堆疊的要求,會發現這是一個約束很強的條件。

注意到,方塊堆疊的要求描述的物件不只是方塊本身,更細地說,它應該描述的是方塊擺放方式。一個長方體方塊有三個面可以作為底(另三個面為對面,面與面對應相同),選擇其中一個面後又需要再分兩種擺放方式。所以對每種方塊應該有六種擺放方式。用向量可以描述這六種擺放方式。前兩個數字表示底面的長和寬,第三個數字表示高。

  1. \((x_i, y_i, z_i)\)
  2. \((y_i, x_i, z_i)\)
  3. \((y_i, z_i, x_i)\)
  4. \((z_i, y_i, x_i)\)
  5. \((x_i, z_i, y_i)\)
  6. \((z_i, x_i, y_i)\)

根據方塊堆疊的要求,我們可以進一步得出,每種方塊擺放方式(共 \(6n\) 種)在堆疊過程中最多出現一次。否則,存在一種擺放方式至少出現了兩次,對於該種方塊擺放方式,無論誰在上誰在下,都會存在一個方塊的底的兩條邊等於另一個方塊的底的兩條邊的情況,與嚴格小於相悖。所以對於每種方塊擺放方式,我們可以選擇“擺放”或是“不擺放”。

我們進一步思考方塊堆疊的要求

,它要保證底的兩條邊都得嚴格小於另一底的兩條邊,因此我們可以先對其中一條邊做一個排序,再保證“選出的所有方塊”的另一條邊堆疊時依次嚴格小於即可。也就是說可以將二維的問題通過預處理排序將為一維的問題,而且可以進一步發現該一維問題是比較典型的動態規劃問題(0-1揹包問題)。

對在 \(x\) 軸上的每條邊做一個排序(從大到小),然後根據 \(y\) 軸上的邊的值選擇“擺放”或是“不擺放”,最後要使得 \(z\) 軸上的值加和最大。