注意 k * n >= m
的情況答案就直接是全部都不選。
- Dynamic Programming
dp[i][j]
: 只有前i
天能選擇的情況能不能在n
天生產剛好j
個產品,j
最大只需計算至2 * m - k * n - 1
。- =
false
ifj < k * n
- 總量比全部都不選還少
- =
true
ifj = k * n
- 全部都不選
- =
false
elsej > k * n && i < 0
- 沒得選
- =
d[i - 1][j]
ifj > k * n && i >= 0 && j < k * n + a[i] * (n - i)
- 第
i
天開始產能增加a[i]
會超過
- 第
- =
d[i - 1][j] || d[i - 1][j - k * n - a[i] * (n - i)]
Otherwise- 加不加產能都試過
- =
- 最後答案是在
dp[n - 1]
這一行當中,和dp[n - 1][m]
最近的true
與其的距離。
- 另一種 Dynamic Programming
dp[i][j]
: 只有前i
天能選擇且m = j
的答案。- =
abs(j - k * n)
ifi < 0 || j <= k * n
- 沒得選或全部都不選
- =
d[i - 1][j]
ifi >= 0 && j > k * n && j <= k * n + a[i] * (n - i) / 2
- 增加產能不會有幫助所以不加
- =
min(d[i - 1][j], d[i - 1][j - a[i] * (n - i)])
ifi >= 0 && j > k * n + a[i] * (n - i) / 2
- 加不加產能都試過
- =
- 最後答案是
d[m]
。
- 另一種 Dynamic Programming
- 把初始產能換成總產量並從需求中先減掉,看還差多少產量。
- 把所有選擇後能獲得產能都換算成產量。
- 把每個選擇視為體積與獲利相等的物品,初始差的產量為背包大小,類似於 0/1 背包問題。
- 轉移式與 0/1 背包相同
dp[i]
為限制上限能最多增加 i 個產量的情況下實際增加的產量- 最佳解實際增加的產量可能超過
m - n * k
,背包容量最大需要做到兩倍的m - n * k
- 枚舉剛剛計算過的背包容量,看哪個與題目要求的的答案最接近。