1 条题解

  • 0
    @ 2026-4-30 0:50:32

    一、题目简述

    mm 个馒头,每个价格 pip_i;有 nn 种盒子,每种容量 CjC_j 和价格 EjE_j,每种盒子最多买一个。 你可以选一些盒子,把馒头装进去(每个盒子装不超过容量的任意数量),按馒头总价卖出。 利润 = 卖出总价 - 盒子总价,没装盒的馒头不算。 求最大利润。

    二、解题思路

    馒头价格不同,肯定优先卖最贵的。 先把馒头价格从大到小排序,并算出前缀和 preipre_i 表示前 ii 个最贵馒头的总价。

    问题变成:选一些盒子,使总容量至少为 xxxx00mm),并让盒子总成本最小,利润就是 prex最小成本pre_x - \text{最小成本},取最大值。

    1. 用背包求最小成本 设 dpcdp_c 表示总容量 恰好 为 cc 的最小盒子总价(0cm0 \le c \le m)。 初始化 dp0=0dp_0=0,其余为无穷大。 对每个盒子(容量 cc,价格 ee),令有效容量 c=min(Cj,m)c = \min(C_j, m)。 因为是 01 背包,我们从 mm 向下循环 jj,用旧 dpjdp_j 更新新容量:

    新容量 t=min(j+c,m)t = \min(j + c, m)

    dpt=min(dpt,dpj+e)dp_t = \min(dp_t, dp_j + e)

    这样就能把总容量超过 mm 的情况也归结到 dpmdp_m 里。

    1. 转为至少容量 计算后缀最小值 suffx=mintxdptsuff_x = \min_{t \ge x} dp_t,表示总容量至少为 xx 的最小成本。 如果 suffxsuff_x 无穷大,说明无法装 xx 个馒头。

    2. 计算答案 枚举 x=0mx = 0 \dots m,若 suffxsuff_x 有限,则利润为 prexsuffxpre_x - suff_x,取最大值。 注意不买盒子时 x=0x=0 利润为 00

    三、代码实现

    #include <bits/stdc++.h>
    #define int long long
    using namespace std;
    const int MAXM = 10005;
    const int INF = 1e18;
    
    int m, n;
    int p[MAXM];
    int pre[MAXM];
    int dp[MAXM];
    
    signed main() {
    	cin.tie(0)->ios::sync_with_stdio(false);
    	cin >> m >> n;
    	for (int i = 1; i <= m; ++i) cin >> p[i];
    	sort(p + 1, p + m + 1, greater<int>());
    	pre[0] = 0;
    	for (int i = 1; i <= m; ++i) pre[i] = pre[i-1] + p[i];
    	for (int i = 0; i <= m; ++i) dp[i] = INF;
    	dp[0] = 0;
    	for (int j = 0; j < n; ++j) {
    		int c, e;
    		cin >> c >> e;
    		c = min(c, m);
    		for (int k = m; k >= 0; --k) {
    			if (dp[k] == INF) continue;
    			int t = min(k + c, m);
    			dp[t] = min(dp[t], dp[k] + e);
    		}
    	}
    	// 后缀最小值
    	for (int i = m-1; i >= 0; --i) {
    		dp[i] = min(dp[i], dp[i+1]);
    	}
    	int ans = 0;
    	for (int x = 0; x <= m; ++x) {
    		if (dp[x] < INF) {
    			ans = max(ans, pre[x] - dp[x]);
    		}
    	}
    	cout << ans << "\n";
    	return 0;
    }
    
    • 1

    信息

    ID
    9007
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者