当前位置: 首页 > news >正文

Luogu P6893 [ICPC 2014 WF] Buffed Buffet 题解

01背包不可以贪心,但是分数背包可以。

分别考虑两种物品然后枚举合并。

对于 D 类食物,令 \(f(i, j)\) 表示前 \(i\) 种菜吃了 \(j\)​ 克时的最大美味值:

\[\begin{aligned} f(i, j) &= \max_{0 \leq k \leq \lfloor \frac{j}{w_i} \rfloor} \left( f(i - 1, j - kw_i) + \sum_{n = 1}^{k}(t_i - (n - 1) \Delta t_i) \right) \\ f(i, j) &= \max_{0 \leq k \leq \lfloor \frac{j}{w_i} \rfloor} \left( f(i - 1, j - kw_i) + kt_i - \frac{\Delta x_i \times k(k - 1)}{2} \right) \end{aligned} \]

注意到 \(i\) 这一维可以压缩掉,处理第 \(i\) 种菜时令 \(g(i)\) 表示前 \(i - 1\) 个物品的结果,算完第 \(i\) 个物品之后更新到 \(f\) 上去就可以。也就是说,对于单个物品 \((w, t, \Delta t)\),转移化简为:

\[f(j) = \max_{0 \leq k \leq \lfloor \frac{j}{w} \rfloor} \left( g(j - kw) + kt - \frac{\Delta t \cdot k(k - 1)}{2} \right) \]

考虑怎么搞掉这个除法下取整,按同余类来分离,将下标按照除以 \(w\) 的余数分类处理。

\(j = j'w + r\),其中 \(0 \leq r \lt w\),则 \(j - kw = (j' - k)w + r\),设 \(i = j' - k\),则有:

\[f(j'w + r) = \max_{0 \leq i \leq j'} \left( g(iw + r) + (j' - i)t - \frac{\Delta t \cdot (j' - i)(j' - i - 1)}{2} \right) \]

展开上面这个式子,重新整理:

\[\begin{aligned} f(j'w + r) &= \max_{i} \left( g(iw + r) + (j' - i)t - \frac{\Delta t}{2}({j'}^2 - 2ij' - j' + i) \right) \\ &= \max_{i} \left( g(iw + r) - it - \frac{\Delta t}{2} i(i + 1) + \Delta t i j' \right) + j't - \frac{\Delta t}{2} j'(j' - 1) \end{aligned} \]

注意到后面抽离出来的东西和 \(i\) 无关,考虑对这个 \(f\) 构造点和斜率,令 \(X(i) = i, Y(i) = g(iw + r) - it - \frac{\Delta t}{2} i(i + 1)\),有:

\[f(j'w + r) = \max_{i} (Y(i) - (-\Delta t j') \times X(i)) + R \]

其中 \(R\) 为无关 \(i\) 常数,这等价于在平面的点 \((X(i), Y(i))\) 中找到使得直线 \(y = kx + b\) 的截距 \(b\) 最大的点,其中斜率 \(k = -\Delta t j'\),由于 \(\Delta t \gt 0\)\(j'\) 递增,\(k\) 递增,单调队列维护凸包。每个决策点 \(i\) 对应点 \((i, Y(i))\),随着 \(j'\) 增大 \(k\) 会负得越来越多越来越陡,最优决策点在凸包上移动。复杂度降到了 \(O(w)\)

考虑对 C 类食品的贪心。每次取当前收益最大的,当两种物品的收益 \(x, y\) 相等时考虑合并得到收益为 \(\frac{1}{\frac{1}{x} + \frac{1}{y}}\),这一部分的复杂度为 \(O(d + w)\)

上面说到的枚举合并指的是枚举划分多少给 C 类剩下的给 B 类。

#include <bits/stdc++.h>using i64 = long long;struct C {int t, dt;
};struct D {int w, t, dt;
};bool inline operator<(const C& a, const C& b) {return a.t > b.t;
}int d, w;
int cc, dc;
std::vector<C> fc;
std::vector<D> fd;namespace Sol1 {int ct, cd, cw, r;std::vector<double> f, g;std::deque<int> q;double x(int p) {return p;}double y(int p) {return g[p * cw + r] - p * ct - 0.5 * cd * p * (p + 1);}double slope(int l, int r) {double lx = x(l), rx = x(r), ly = y(l), ry = y(r);return (ry - ly) / (rx - lx == 0 ? 1e-10 : rx - lx);}void ins(int p) {while (q.size() > 1 && slope(q[q.size() - 2], q.back()) < slope(q[q.size() - 2], p)) q.pop_back();q.push_back(p);}void del(double k) {while (q.size() > 1 && slope(q.front(), q[1]) > k) q.pop_front();}void add(int wi, int t, int dt) {cw = wi, ct = t, cd = dt;for (int i = 1; i <= w; i++) {g[i] = f[i];f[i] = -1e18;}for (r = 0; r < cw; r++) {q.clear();for (int j = 0; j * cw + r <= w; j++) {ins(j);del(-dt * j);int i = q.front();f[j * cw + r] = std::max(f[j * cw + r], g[i * cw + r] + (j - i) * t - 0.5 * (j - i) * (j - i - 1) * dt);}}}void calc() {f.assign(w + 1, -1e18);g.resize(w + 1);for (int i = 1; i <= dc; i++) add(fd[i].w, fd[i].t, fd[i].dt);}
}namespace Sol2 {std::vector<double> f;void calc() {f.resize(w + 1);if (cc == 0) {for (int i = 1; i <= w; i++) f[i] = -1e18;return;}std::sort(fc.begin() + 1, fc.begin() + cc + 1);int p = 1;double cur = fc[1].t, cdt = fc[1].dt, cw = 0, sum = 0;p++;for (int i = 1; i <= w; i++) {while (cw < i) {if (p > cc || cur - cdt * (i - cw) > fc[p].t) {sum += cur * (i - cw) - 0.5 * (i - cw) * (i - cw) * cdt;cur -= cdt * (i - cw), cw = i;} else {double q = (cur - fc[p].t) / cdt;sum += cur * q - 0.5 * q * q * cdt;cur = fc[p].t, cw += q;cdt = 1.0 / (1.0 / cdt + 1.0 / (fc[p].dt != 0 ? fc[p].dt : 1e-10));p++;}}f[i] = sum;}}
}int main() {std::ios::sync_with_stdio(false);std::cin.tie(nullptr);std::cin >> d >> w;fc.resize(d + 1);fd.resize(d + 1);while (d--) {char tp[10];std::cin >> tp;if (tp[0] == 'D') {++dc;std::cin >> fd[dc].w >> fd[dc].t >> fd[dc].dt;} else {++cc;std::cin >> fc[cc].t >> fc[cc].dt;}}Sol1::calc();Sol2::calc();double ans = -1e18;for (int i = 0; i <= w; i++) ans = std::max(ans, Sol2::f[i] + Sol1::f[w - i]);if (cc == 0 && ans < -1e16) std::cout << "impossible\n";else std::cout << std::fixed << std::setprecision(10) << ans << "\n";return 0;
}
http://www.gsyq.cn/news/56487.html

相关文章:

  • 性能优化 | HarmonyOS预加载,三步即可提升APP页面的响应速度
  • CF1437F Emotional Fishermen
  • 习题解析之:汽车限行
  • 量子力学作业6
  • WSL2调用摄像头并使用OpenCV - 教程
  • 2025湛江一对一辅导机构测评榜:从城区到县域的靠谱补习方案全解析
  • 如何结合langchain、neo4j搭建关联检索问答
  • 2025年四川科技展馆设计公司权威推荐榜单:科技展厅设计/科技展览设计/城市规划馆设计源头公司精选
  • 学习率对于PPO训练的作用
  • 2025 最新推荐碳纤木门厂家口碑排行榜:PUR 无缝封边 + 45 磁吸静音技术领衔,环保无甲醛优质企业全解析耐磨防刮/环保无甲醛/防污易清洁/耐腐蚀/铝/LVL 龙骨/复合碳纤木门公司推荐
  • 2025年牛粪有机肥翻抛机供应商权威推荐榜单:轮盘式翻抛机/链式翻抛机/槽式翻抛机设备源头厂家精选
  • 2025年电力电缆生产厂家权威盘点(11月新):中低、低压、中压、变频、聚乙烯绝缘、聚氯乙烯绝缘电缆生产厂家推荐
  • 卡码网47:Djikstra算法
  • CF2165F Arctic Acquisition 题解
  • 2025年哈尔滨心理咨询学校权威推荐榜单:特殊教育/早教中心/口肌训练源头学校精选
  • Day30:2025年10月20日,星期一,值班,诸事皆顺。
  • 绍兴一对一家教辅导机构推荐:2025权威测评排行榜,第一个性价比最高
  • 天门一对一家教机构终极推荐:2026最新辅导机构口碑TOP榜单!真实反馈闭眼选
  • 计算机视觉:YOLO实现目标识别+目标跟踪技术 pyqt界面 OpenCV 计算机视觉 深度学习 计算机(建议收藏)✅ - 指南
  • 潜江一对一课外补习机构推荐:2026 最新教育机构天花板榜单!提分快还省钱
  • 2025恩施一对一家教机构综合推荐,提分优选:靠谱方案推荐排行榜
  • SATA接口调试问题记录
  • 镜头分辨率如何匹配工业相机的分辨率
  • 洛谷 B4410:[GESP202509 一级] 金字塔 ← 循环结构
  • CF246E bfs 序上莫队
  • 小型食品厂省心了!CLC-S22R 控温又省成本​
  • 2025 最新推荐装盒机厂家权威排行榜:全自动 / 食品 / 纸巾 / 卫生巾装盒机技术创新与整线配套能力测评
  • Galera Cluster部署 - 详解
  • 模拟机问题
  • 2025年主流学习机品牌差异化分析与选购指南