存錢罐空重 E、滿重 F,容量 V = F-E。
有 N 種硬幣,每種價值 P[i]、重量 W[i]。
求恰好裝滿容量 V 的最小總價值。若不可能輸出 "This is impossible."。
dp[j]:重量恰好為 j 的最小價值。dp[0]=0,dp[1..V]=INF(極大值,如 1e9)。for i: for j=W[i]..V: dp[j] = min(dp[j], dp[j-W[i]] + P[i])。dp[V]==INF 即不可能。
#include <stdio.h>
int p[1008], w[1008];
int dp[10000];
int main() {
int T, E, F, V, N;
scanf("%d", &T);
while (T--) {
scanf("%d%d", &E, &F);
V = F - E;
for (int i=0; i<=V; i++) dp[i] = 9999999;
dp[0] = 0;
scanf("%d", &N);
for (int i=0; i
| 背包類型 | 初始化 | 求最小值 | 求最大值 |
|---|---|---|---|
| 01 背包 | dp[0]=0, 其他 -INF/INF | dp[j]=min(dp[j], dp[j-w]+v) | dp[j]=max(dp[j], dp[j-w]+v) |
| 完全背包 | dp[0]=0, 其他 -INF/INF | 正序 j 循環 | 正序 j 循環 |
| 多重背包 | 同上 | 二進制拆分/單調隊列 | 同上 |
「恰好裝滿」關鍵在於非 0 狀態初始化為極值,而「不超過容量求最優」則初始化為 0。