完全背包习题题解(洛谷题单)

本篇对应源码见仓库 solutions/xcpc/algorithm/dp/knapsack-complete/。

P1616 疯狂的采药

题意

完全背包的模板题。

思路

模板题

示例代码

signed main() {
    IOS;

    int t, m;
    cin >> t >> m;
    vector<int> a(m + 1), b(m + 1);
    fer(i, 1, m + 1) cin >> a[i] >> b[i];

    vector<int> dp(t + 1);

    fer(i, 1, m + 1) {
    	fer(j, a[i], t + 1) {
    		dp[j] = max(dp[j], dp[j - a[i]] + b[i]);
    	}
    }

    cout << dp[t] << '\n';

    return 0;
}

P2722 USACO3.1总分 Score Inflation

题意

这也是一道模板题。

思路

模板题

示例代码

signed main() {
    IOS;

    int m, n;
    cin >> m >> n;
    vector<int> p(n + 1), t(n + 1);
    fer(i, 1, n + 1) cin >> p[i] >> t[i];

    vector<int> dp(m + 1);
    fer(i, 1, n + 1) {
    	fer(j, t[i], m + 1) {
    		dp[j] = max(dp[j], dp[j - t[i]] + p[i]);
    	}
    }
    cout << dp[m] << '\n';

    return 0;
}

P1853 投资的最大效益

题意

加强的完全背包,背包的容量会随着年份的增长(价值的变化)而动态的增加。

思路

对每一年都进行完全背包,更新背包的最大容量。
需要注意对背包容量的优化处理,可以整除1000。

示例代码

signed main() {
    IOS;

    int s, n, d;
    cin >> s >> n >> d;
    vector<int> a(d + 1), b(d + 1);
    fer(i, 1, d + 1) cin >> a[i] >> b[i];

    vector<int> dp(N);
    fer(_, 0, n) {
    	int m = s / 1000;
    	fer(i, 1, d + 1) {
    		fer(j, a[i] / 1000, m + 1) {
    			dp[j] = max(dp[j], dp[j - a[i] / 1000] + b[i]);
    		}
    	}
    	s += dp[m];
    	dp.clear();
    }
    cout << s << '\n';

    return 0;
}

P2918 USACO08NOV Buying Hay S

题意

完全背包的改版,题目描述有所不同。题目求价值达到标准需要的最小的背包容量。

思路

根据数据范围可以计算出背包容量的最大上限,然后进行完全背包,当能达到价值的标准时对当前背包容量取 \(min\) 即可。

示例代码

signed main() {
    IOS;

    int n, h;
    cin >> n >> h;
    vector<int> p(n + 1), c(n + 1);
    fer(i, 1, n + 1) cin >> p[i] >> c[i];

    vector<int> dp(N);
    int ans = inf;

    fer(i, 1, n + 1) {
    	fer(j, c[i], N) {
    		dp[j] = max(dp[j], dp[j - c[i]] + p[i]);
    		if(dp[j] >= h) {
    			ans = min(ans, j);
  				break;
    		}
    	}
    }
    cout << ans << '\n';
    return 0;
}
posted @ 2026-11-11 06:23  slowbyte  阅读(2)  评论(0)    收藏  举报