切換
舊版
前往
大廳
主題

ZeroJudge - c271: 疊疊樂(Easy) 解題心得

Not In My Back Yard | 2019-08-22 23:11:40 | 巴幣 2 | 人氣 271

題目連結:


題目大意:
給定一正整數 T (T ≦ 100),代表有 T 筆的測試資料。每筆測資的第一列給定一正整數 N (1 ≦ N ≦ 1000),代表有 N 個箱子。接著的 N 列輸入,每列給定三正整數 W 、 S 、 L (1 ≦ W 、 S 、 L ≦ 10 ^ 9),分別代表一個箱子的重量、最大負重(包含自身的重量)以及長度。

箱子等高、等寬,且可以疊在一起,但要滿足以下條件:
一:長度由上至下非嚴格遞增(也就是放在上面的箱子長度不會超過下面的)
二:任何箱子的上面如果有放其他箱子,則上面的所有箱子之總重(含自己)不超過其最大負重。

試問:最多可以疊幾個箱子?



範例輸入:
2
2
2 4 2
8 10 3
2
2 4 2
8 9 3


範例輸出:
2
1


解題思維:
首先,將箱子們先以長度由小排到大,長度一樣的再以最大負重由小排到大。

接著建立一個一維陣列 DP[i] ,每個 i 值代表「目前」高度為 i 個箱子的塔總重量之最小值。一開始皆初始化為極大的值。代表一開始「目前」的陣列 DP ,沒有任何箱子放入。

因此,我們一個箱子一個箱子地試放看看(以排序後的順序,而且每次都是放在箱子塔的最下面)。可以看到高度為 i 個箱子要放入此箱子時,塔的總重有可能變為從 i - 1 個箱子的塔放入此箱而得,或者是維持上一個的放法,端看哪座最後總重較小。即:
DP[i] = min( DP[i], DP[i - 1] + weight[j] ),其中 weight[j] 代表現在的箱子(編號 j)的重量。

但是在放入之前,要先判斷該塔(DP[i])目前的重量是否超過現在箱子的最大負重。如果超過,也就無法放入(因為箱子要放到最下面),更不用提會去影響現在的塔之重量最小值。

因為 DP[i - 1] 有可能會影響 DP[i]  ,因此求目前最佳解的順序應為從大的 i 值到小的 i 值去求。否則,方向錯誤的話會影響解答,因為這樣子會無法判斷這個箱子放入之前和之後的狀態變化。

最後,所有箱子都試著放入後,看陣列 DP 中第一個不是儲存一開始的極大值的位置 i ( i 由大到小看)為何。此時的 i 值即為所求。

此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。

創作回應

胖胖貓
為了動態規劃而預先排序,但是我對於排序的規則抱持疑問?
優先依據長度這點沒有問題,但問題是其次是依據"最大負重",最大負重的定義到底要不要扣除本身的重量?扣除的話可以當作承受其他箱子總和的重量能力,我自己覺得應該要根據扣除自身重量後能承受的重量排序,但這麼做只會拿到 51%。
#0: 12% WA (line:5)
您的答案為: 1
正確答案為: 2
#1: 12% WA (line:1)
您的答案為: 33
正確答案為: 34
#2: 12% AC (5ms, 328KB)
通過檢測
#3: 12% WA (line:1)
您的答案為: 30
正確答案為: 31
#4: 13% WA (line:7)
您的答案為: 11
正確答案為: 12
#5: 13% AC (52ms, 304KB)
通過檢測
#6: 13% AC (47ms, 348KB)
通過檢測
#7: 13% AC (2ms, 340KB)
通過檢測
2020-08-18 20:04:37
胖胖貓
感謝批踢踢的 DJWS 大大回覆關鍵字:烏龜塔問題

nicknick0630.github.io/2019/03/07/UVa-10154-Weights-and-Measures/
2020-08-21 10:33:17
心彩
一開始"皆"初始化為極大的值 錯字
2023-05-29 09:29:32
Not In My Back Yard
感謝,已更正。
2023-05-29 18:00:04

更多創作