初始資金 V,year 年。每年有 n 種投資項目,項目 i 成本 c[i](千元倍數),收益 w[i]。每年可重複投資同一項目(完全背包),年終本金加收益作為下一年本金。求最終資金。
每年本金 V 固定,背包容量 cap = V / 1000(千元單位)。
項目:重量 c[i]、價值 w[i],**可無限選取** → 完全背包。
年終最大收益 dp[cap],新本金 V += dp[cap]。
for (int i = 0; i < n; i++) // 遍歷物品
for (int j = c[i]; j <= cap; j++) // 正序遍歷容量(關鍵!)
dp[j] = max(dp[j], dp[j - c[i]] + w[i]);
正序遍歷容量體現「可重複選取」。
#include
#include
#include
using namespace std;
int c[20], w[20], dp[100000];
int main() {
int T; scanf("%d", &T);
while (T--) {
int V, year, n;
scanf("%d%d", &V, &year);
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%d%d", &c[i], &w[i]);
c[i] /= 1000; // 單位統一為千元
}
while (year--) {
int cap = V / 1000;
memset(dp, 0, sizeof(dp)); // 每年重置!
for (int i = 0; i < n; i++)
for (int j = c[i]; j <= cap; j++)
dp[j] = max(dp[j], dp[j - c[i]] + w[i]);
V += dp[cap];
}
printf("%d\n", V);
}
return 0;
}
O(n × cap),cap ≤ V/1000,V 增長但數據範圍可控O(year × n × cap)O(cap)多年投資問題分解為**獨立的年度完全背包**。關鍵在於識別「每年決策獨立、項目可重複投資」的完全背包特徵,並正確處理單位換算與年度疊代。模板級完全背包寫法直接適用。