需採購 a、b、c 三類原件滿足建造需求(a:500, b:400, c:300),四商人報價不同,求最小成本組合。原代碼採用四重循環窮舉,邏輯基本正確,但**最終輸出使用了循環變量 i,j,k,l 而非最優解 x,y,z,w**,導致結果錯誤。
printf("最後買到a%d個,b%d個,c%d個\n",
2*i+2*j+5*k+4*l, 4*i+j+2*k+3*l, 2*i+3*j+2*k+2*l); // ❌ i,j,k,l 循環結束時均為 100
應改為記錄的最優解 x,y,z,w:
printf("最後買到a%d個,b%d個,c%d個\n",
2*x+2*y+5*z+4*w, 4*x+y+2*z+3*w, 2*x+3*y+2*z+2*w); // ✅
| 方案 | 時間複雜度 | 空間 | 適用場景 |
|---|---|---|---|
| 四重循環窮舉 | O(N⁴) = 10⁸ | O(1) | N=100 邊界可接受,秒級運行 |
| 三重循環 + 推導 | O(N³) | O(1) | 利用方程式減少一層循環 |
| 整數線性規劃 (ILP) | 指數級(理論) | O(變量數) | 大規模、多約束,用 GLPK/CPLEX |
| 動態規劃 (背包變體) | O(需求量 × 商人數) | O(需求量) | 需求量較小時極快 |
將每個商人視為一種「物品」,購買一次消耗 1 元,獲得 (a_i, b_i, c_i) 原件。目標:最小化總成本,滿足需求向量 ≥ (500,400,300)。
// 狀態 dp[i][j][k] = 獲得至少 i a、j b、k c 的最小花費
// 初始 dp[0][0][0] = 0,其餘 INF
// 轉移:對每個商人 (da,db,dc, cost=1)
for (int i = needA; i >= 0; --i)
for (int j = needB; j >= 0; --j)
for (int k = needC; k >= 0; --k)
dp[min(i+da,needA)][min(j+db,needB)][min(k+dc,needC)] =
min(dp[...], dp[i][j][k] + 1);
狀態數 501×401×301 ≈ 6千萬,較大,可壓縮維度或用 BFS/優先隊列 (Dijkstra) 求最短路。
ceil(需求/單次最小產出),如 a 類最小單次產出 2,上限 250 即可,而非死板 100。窮舉法在小規模離散優化中簡單有效;大規模場景請轉向運籌學建模工具。