P3826 [NOI2017] 蔬菜 题解

news/2025/2/12 20:51:59/文章来源:https://www.cnblogs.com/Scarab/p/18712126

Description

\(n\) 种蔬菜,对于所有的满足条件 \(d\times x_i \leq c_i\) 的正整数 \(d\) ,有 \(x_i\) 个单位的蔬菜将在 第 \(d\) 天结束时变质。

特别地,若 \((d - 1)\times x_i \leq c_i < d\times x_i\) ,则有 \(c_i - (d - 1)\times x_i\) 单位的蔬菜将在第 \(d\) 天结束时变质。

注意,当 \(x_i = 0\) 时,意味着这种蔬菜不会变质。

同时,每天销售的蔬菜,总量也是有限的,最多不能超过 \(m\) 个单位。

现在,小 N 有 \(k\) 个问题,想请你帮忙算一算。每个问题的形式都是:对于已知的 \(p_j\),如果需要销售 \(p_j\) 天,最多能获得多少收益。

\(n,p_j\leq 10^5,m\leq 10\)

Solution

首先考虑怎么建出费用流模型。

注意到每天会有蔬菜消失,很难处理,所以考虑时空倒流,这样就变为每天会有一些蔬菜添加进去。

建立源点 \(S\),汇点 \(T\),定义 \((t,i)\) 表示第 \(t\) 天第 \(i\) 种蔬菜对应的点,\([t]\) 表示第 \(t\) 天采购对应的点,则可以连出如下边:

  • \((S,(t,i),a_i,\max\{c_i-(t-1)\times x_i,0\})\)
  • \(((t,i),(t-1,i),+\infty,0)\)
  • \(((t,i),[t],+\infty,0)\)
  • \(([t],T,m,0)\)

但是这里没有考虑每种蔬菜第一次买的 \(s_i\) 的贡献,这也是好处理的,只需要将 \(i\) 蔬菜第一次出现的时刻里选一个边的边权变为 \(a_i+s_i\) 即可,容易发现一个蔬菜如果被选就一定优先选这个特殊边。

考虑如何模拟这个费用流。

这里用每次加点的方式跑。观察上图会发现只有 II 和 III 种增广路是有效的,而这两种都不会退流,所以 \([1,t]\) 时刻最优解用到的蔬菜一定是 \([1,t-1]\) 的超集,而 \([1,t]\) 的所有蔬菜放到 \([1,t-1]\) 不考虑每天销售限制的话都能用,所以如果求出 \([1,t]\) 的蔬菜,将这些用到的按照权值从大到小排序即可得到 \([1,t-1]\) 的蔬菜。

现在只需要求出 \([1,10^5]\) 所用到的蔬菜即可,同样考虑时空倒流,用一个堆维护目前没被用完的蔬菜的权值和出现次数。注意到我们不能每次都更新每个蔬菜的剩余数量,但是由于只需要找到出现次数至少一次的蔬菜,所以当某个蔬菜删空了再更新数量即可。

时间复杂度:\(O(nm\log n)\)

Code

#include <bits/stdc++.h>// #define int int64_tusing i64 = int64_t;const int kMaxN = 1e5 + 5, kMaxT = kMaxN * 10;int n, m, k, t;
int a[kMaxN], s[kMaxN], c[kMaxN], x[kMaxN], lst[kMaxN], now[kMaxN];
i64 veg[kMaxT], ans[kMaxT];
std::vector<std::tuple<int, int, int>> vec[kMaxN];int gettime(int c, int x) {if (!x) return 1e5;else return (c - 1) / x + 1;
}void solve() {std::priority_queue<std::tuple<int, int, int>> q;for (int c = 1e5; c; --c) {for (auto [x, w, cnt] : vec[c])q.emplace(w, x, cnt), now[x] += cnt;std::vector<int> vv;for (int cc = 1; cc <= m && !q.empty(); ++cc) {auto [w, i, cnt] = q.top(); q.pop();veg[++t] = w, --now[i], --cnt;if (cnt) q.emplace(w, i, cnt);if (!now[i] && x[i]) {if (lst[i] > c) q.emplace(a[i], i, now[i] += x[i] * (lst[i] - c)), lst[i] = c;else vv.emplace_back(i);}}for (auto i : vv) q.emplace(a[i], i, now[i] += x[i]), lst[i] = c - 1;}std::sort(veg + 1, veg + 1 + t, std::greater<>());for (int i = 1; i <= t; ++i) ans[i] = ans[i - 1] + veg[i];
}void dickdreamer() {std::cin >> n >> m >> k;for (int i = 1; i <= n; ++i) {std::cin >> a[i] >> s[i] >> c[i] >> x[i];vec[gettime(c[i], x[i])].emplace_back(0, a[i] + s[i], 1);--c[i];if (c[i]) {int t = gettime(c[i], x[i]);lst[i] = t;vec[t].emplace_back(i, a[i], c[i] - x[i] * (t - 1));}}solve();for (int i = 1; i <= k; ++i) {int p;std::cin >> p;std::cout << ans[std::min(p * m, t)] << '\n';}
}int32_t main() {
#ifdef ORZXKRfreopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout);
#endifstd::ios::sync_with_stdio(0), std::cin.tie(0), std::cout.tie(0);int T = 1;// std::cin >> T;while (T--) dickdreamer();// std::cerr << 1.0 * clock() / CLOCKS_PER_SEC << "s\n";return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/882733.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

什么是token?token是用来干嘛的?

从事计算机行业的朋友都听说过token这么个东西,尤其是deepseek爆火后api(大家都知道什么意思吧),但是其他行业的人就很少了解到token,下面就给大家来详细介绍一下token是什么意思?token是用来干嘛的这一块的内容,希望能帮助到大家。token是什么意思? 作为计算机术语时,…

uniapp 开发app流程

准备: DCLOUD开发者账号、IOS开发者账号、高德地图开发者账号 1、在DCLOUD平台创建【应用】在应用中设置【各平台信息】,安卓的包名自己写一个,ios BundleId在ios开发者账号中获取,本教程以安卓为主,ios方面的问题暂时忽略记住这个列表中的 安卓的包名 和 ISO的域名/Bundl…

智能驾驶中的 感知 模块介绍

在自动驾驶系统中,感知技术是核心基础之一。感知技术为车辆提供环境信息,使其能够实现对周围环境的理解、分析与决策,从而保证安全性和高效性。通常大家对感知的介绍停留在“眼睛”的作用,但这样的解释太宽泛了例如感知到底是什么?由哪些模块组成?输入输出有什么含义?数…

AI行为识别摄像机

AI行为识别摄像机具备24小时不间断的视频监控能力,可以随时捕捉现场动态,确保无死角覆盖。通过训练好的模型,该设备能够对不同的人类活动进行分类和判断,从而有效区分正常与异常行为。例如,在商场中,当检测到顾客有异常举动时,系统会立即发出警报。相比于传统监控设备,…

【笔记】多项式Ⅰ:

前言 这一节用于讲解拉格朗日插值法(Lagrange Polynomial)和快速傅里叶变换(Fast Fourier Transform),但是含有前置知识,因此有大量学过的知识可以直接跳过,存在大量证明会放出相应的链接。 多项式 基本概念 我们将形如 \(\textstyle{\sum a_nx^n}\) 的有限项相加式子成…

睡岗智能识别摄像机

睡岗智能识别摄像机具备24小时不间断的视频监控能力,可以随时查看现场情况,并记录所有视频数据。通过深度学习算法,该设备能够分析视频流中的人物行为,准确判断是否存在“睡岗”现象。一旦检测到异常情况,系统会自动向管理人员发送警报信息,以便迅速处理。所有录像资料都…

微分信号作用量

微分信号传递函数 \[G(s) = \frac{Ts}{Ts+1} \]阶跃响应 单位阶跃函数\(u(t)\) 的拉普拉斯变化为 \(U(s)=\frac{1}{s}\) \[Y(s)=G(s)U(s)=\frac{T}{Ts+1} \]对\(Y(s)\) 进行拉普拉斯反变换,得到微信信号的阶跃响应曲线 \[y(t) = e^{-\frac{t}{T}}u(t) \]对\(y(t)\) 进行积分,可…

非车间人员进入识别监控系统

非车间人员进入识别监控系统的核心是 YOLOX 深度学习算法,非车间人员进入识别监控系统通过现场监控摄像机覆盖了车间及周边的各个关键区域,当系统检测到非车间人员进入时,会迅速触发告警流程。首先,系统会在现场通过语音提醒装置发出语音警告,要求其立即离开。同时,系统会…

用AI绘制CAD气温曲线图

此文章视频讲解地址 https://www.bilibili.com/video/BV1JtKjenEhF 需求 根据气温的JSON数据,用AI自动生成CAD格式的气温曲线DWG图 数据准备 用deepseek获取了北京市最近一个月的气温json数据AI对话 首先进入唯杰地图云端管理平台 选择与唯杰地图AI对话需求描述 1、要弹出一个…

攻防世界-RE-BABYRE

这道题目比较有趣,首先我们分析它是一个不套壳的程序,然后直接用IDA打开他的加密逻辑也很直观:flag一定十个长度为14的字符串 judge在这里是一个函数指针,指向judge数组的第一位可是当我们点击judge却无法查看它的程序逻辑。 我们注意到在上面有这样一段程序for ( i = 0; i…

相机模型(Camera Models)总结

针孔相机(Pinhole camera)如图所示,这是一个比较简单的针孔相机模型,这里的树是我们需要拍摄的物体,记作object,从物体身上不同点发出不同颜色的光线。 barrier表示的是障碍,它位于物体和胶片之间,具有阻挡光线的作用。 Aperture 表示针孔,即障碍物上的一个小孔。光线…

C++代码改造为UTF-8编码问题的总结

详细介绍将C++程序代码改造为UTF-8编码时可能遇到的问题,以及具体的解决方案;同时介绍了字符编码的相关知识。1. 引言 无论是哪个平台哪种编程语言,字符串乱码真是一个让人无语的问题:你说这个问题比较小吧,但是关键时刻来一下真是受不了。解决方式也有很多种,但是与其将…