有 n (≤30) 個物品,第 i 個耗時 ti、價值 vi、最早可完成時間 li(在此之前完成會被判定作弊)。需選擇物品使總價值 ≥ w,求最小總耗時。物品不可分割,一次只能做一個。
物品 i 若在時刻 T 完成,需滿足 T ≥ li。即其開始時間 ≥ li - ti。為了讓 DP 狀態合法,按 li - ti 從小到大排序。這樣在考慮前 i 個物品時,當前時間 T 若 ≥ li - ti,則後續物品的限制自動滿足(因為它們的 l-t 更大)。
dp[j]:花費總時間恰為 j 所能獲得的最大價值。dp[0]=0,其餘 -INF。dp[j] = max(dp[j], dp[j-t_i] + v_i)。dp[j] ≥ w 的最小 j。最大時間上界 up = max(∑ti, max li)。實際只需 DP 到 up。
struct Item { int t, v, l; };
bool cmp(Item a, Item b) { return a.l - a.t < b.l - b.t; }
int dp[MAX_TIME];
while (scanf("%d%d", &n, &w) != EOF) {
for (int i=0;i=item[i].t; --j) {
if (j >= item[i].l)
dp[j] = max(dp[j], dp[j-item[i].t] + item[i].v);
}
}
int ans = -1;
for (int j=0;j<=up;++j) if (dp[j] >= w) { ans=j; break; }
if (ans==-1) puts("zhx is naive!");
else printf("%d\n", ans);
}
HDU 5188 是帶時間窗約束的 01 背包。核心技巧:按 l-t 排序將時間約束轉化為 DP 狀態的合法性條件,配合滾動數組優化空間。體現了「排序 + DP」在約束優化問題中的通用思想。