\(\mathcal{Description}\)

  Link.

  给定你初始拥有的钱数 \(C\) 以及 \(N\) 台机器的属性,第 \(i\) 台有属性 \((d_i,p_i,r_i,g_i)\),分别是出售时间、售价、转卖价、单日工作收益。机器在买入或转卖当天不提供收益,且你同一时刻最多拥有一台机器,在 \((D+1)\) 天时必须转卖拥有的机器。求第 \((D+1)\) 天你拥有的最大钱数。\(n\le10^5\)。

\(\mathcal{Solution}\)

  比较自然的想法时依时间顺序 DP,所以先将机器按时间排序。令 \(f(i)\) 表示在 \(d_i\) 时刻,卖掉手里的机器后拥有的最大钱数,添加一台虚拟机器 \((D+1,0,0,0)\) 用于收集答案。考虑转移:

\[f(i)=\max_{f(j)\ge p_j}\{f(j)-p_j+r_j+g_j(d_i-d_j-1)\}.
\]

注意同一天多次买卖机器显然不优,所以 \(g_j\) 的系数不需要对 \(0\) 取 \(\max\)。这个一看就是斜优的样子,研究 \(f(u),f(v)\) 对 \(i\) 的转移:

\[\begin{aligned}
&f(u)-p_u+r_u+g_u(d_i-d_u-1)>f(v)-p_v+r_v+g_v(d_i-d_v-1) \\
\Longleftrightarrow~~~~&[f(u)-p_u+r_u-g_u(d_u+1)]-[f(v)-p_v-r_v-g_v(d_v+1)]>(g_v-g_u)d_i \\
\Longleftrightarrow~~~~&\frac{h(u)-h(v)}{g_u-g_v}<-d_i~~~~(g_u<g_v).
\end{aligned}
\]

  很遗憾我们需要 \(g_u<g_v\) 控制符号,所以无法保证此时斜率 \(-d_i\) 的单调性,所以得写一发 CDQ 或者李超树。复杂度都是 \(\mathcal O(n\log n)\)。

\(\mathcal{Code}\)

/*+Rainybunny+*/

#include <bits/stdc++.h>

#define rep(i, l, r) for (int i = l, rep##i = r; i <= rep##i; ++i)
#define per(i, r, l) for (int i = r, per##i = l; i >= per##i; --i) typedef long long LL;
typedef long double LD; inline void chkmax(LL& u, const LL v) { u < v && (u = v); } const int MAXN = 1e5;
int N, C, D;
LL f[MAXN + 5], g[MAXN + 5];
struct Machine { int day, buy, sel, pro; } mch[MAXN + 5]; inline LD slope(const int u, const int v) {
return LD(g[u] - g[v]) / (mch[u].pro - mch[v].pro);
} inline std::vector<int> solve(const int l, const int r) {
if (l == r) {
chkmax(f[l], C);
g[l] = f[l] - mch[l].buy + mch[l].sel
- mch[l].pro * (mch[l].day + 1ll);
// printf("f(%d)=%lld\n", l, f[l]);
return f[l] >= mch[l].buy ? std::vector<int>{ l } : std::vector<int>{};
} int mid = l + r >> 1;
auto&& cvxL(solve(l, mid));
for (int i = 0, j = mid + 1; j <= r; ++j) {
while (i + 1 < int(cvxL.size())
&& slope(cvxL[i], cvxL[i + 1]) >= -mch[j].day) ++i;
if (i < int(cvxL.size())) { // maybe cvxL is empty.
int p = cvxL[i];
chkmax(f[j], f[p] - mch[p].buy + mch[p].sel
+ mch[p].pro * (mch[j].day - mch[p].day - 1ll));
}
}
auto&& cvxR(solve(mid + 1, r)); std::vector<int> ret;
auto push = [&](const int u) { // maintain the up-convex.
while (ret.size() > 1 && slope(ret[ret.size() - 2], ret.back())
<= slope(ret.back(), u)) ret.pop_back();
ret.push_back(u);
}; for (size_t i = 0, j = 0; i < cvxL.size() || j < cvxR.size();) {
if (i < cvxL.size() && j < cvxR.size()
&& mch[cvxL[i]].pro == mch[cvxR[j]].pro) {
++(g[cvxL[i]] < g[cvxR[j]] ? i : j); // pass the smaller one.
} else if (j == cvxR.size()
|| (i < cvxL.size() && mch[cvxL[i]].pro < mch[cvxR[j]].pro)) {
push(cvxL[i++]);
} else {
push(cvxR[j++]);
}
}
return ret;
} int main() {
std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0); while (std::cin >> N >> C >> D && N | C | D) {
rep (i, 1, N) {
std::cin >> mch[i].day >> mch[i].buy >> mch[i].sel >> mch[i].pro;
}
std::sort(mch + 1, mch + N + 1,
[](const Machine& u, const Machine& v) { return u.day < v.day; });
mch[++N] = { D + 1, 0, 0, 0 };
rep (i, 1, N) f[i] = g[i] = 0; solve(1, N);
static int cas = 0;
std::cout << "Case " << ++cas << ": " << f[N] << '\n';
} return 0;
}

Solution -「WF2011」「BZOJ #3963」MachineWorks的更多相关文章

  1. 「BZOJ 4228」Tibbar的后花园

    「BZOJ 4228」Tibbar的后花园 Please contact lydsy2012@163.com! 警告 解题思路 可以证明最终的图中所有点的度数都 \(< 3\) ,且不存在环长是 ...

  2. 「BZOJ 3645」小朋友与二叉树

    「BZOJ 3645」小朋友与二叉树 解题思路 令 \(G(x)\) 为关于可选大小集合的生成函数,即 \[ G(x)=\sum[i\in c ] x^i \] 令 \(F(x)\) 第 \(n\) ...

  3. 「BZOJ 4502」串

    「BZOJ 4502」串 题目描述 兔子们在玩字符串的游戏.首先,它们拿出了一个字符串集合 \(S\),然后它们定义一个字符串为"好"的,当且仅当它可以被分成非空的两段,其中每一段 ...

  4. 「BZOJ 4289」 PA2012 Tax

    「BZOJ 4289」 PA2012 Tax 题目描述 给出一个 \(N\) 个点 \(M\) 条边的无向图,经过一个点的代价是进入和离开这个点的两条边的边权的较大值,求从起点 \(1\) 到点 \( ...

  5. 「BZOJ 2534」 L - gap字符串

    「BZOJ 2534」 L - gap字符串 题目描述 有一种形如 \(uv u\) 形式的字符串,其中 \(u\) 是非空字符串,且 \(v\) 的长度正好为 \(L\), 那么称这个字符串为 \( ...

  6. 「BZOJ 2956」模积和

    「BZOJ 2956」模积和 令 \(l=\min(n,m)\).这个 \(i\neq j\) 非常不优雅,所以我们考虑分开计算,即: \[\begin{aligned} &\sum_{i=1 ...

  7. Solution -「CTS 2019」「洛谷 P5404」氪金手游

    \(\mathcal{Description}\)   Link.   有 \(n\) 张卡牌,第 \(i\) 张的权值 \(w_i\in\{1,2,3\}\),且取值为 \(k\) 的概率正比于 \ ...

  8. 「雅礼集训 2018 Day2」农民

    传送门 Description  「搞 OI 不如种田.」 小 D 在家种了一棵二叉树,第 ii 个结点的权值为 \(a_i\). 小 D 为自己种的树买了肥料,每天给树施肥. 可是几天后,小 D 却 ...

  9. 「题解」「美团 CodeM 资格赛」跳格子

    目录 「题解」「美团 CodeM 资格赛」跳格子 题目描述 考场思路 思路分析及正解代码 「题解」「美团 CodeM 资格赛」跳格子 今天真的考自闭了... \(T1\) 花了 \(2h\) 都没有搞 ...

随机推荐

  1. 怎样修改自己的登录shell

    问题 我只是Linux系统的普通用户,没有权限调用chsh命令修改自己的登录shell. bash-4.1$ chsh --help Usage: chsh [ -s shell ] [ --list ...

  2. GDB基础知识

    GDB 基础知识 GDB 基础知识 一.简介 支持命令补全功能 GDB 的调用与退出 二.GDB 的基本指令 1. run/r 2. break/b 3. info breakpoints 4. de ...

  3. HDU 2044 一只小蜜蜂... (斐波那契数列)

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=2044 题目分析:其实仔细读题就会发现其中的规律, 其中:这是一个典型的斐波那契数列. 代码如下: #i ...

  4. netty系列之:一口多用,使用同一端口运行不同协议

    目录 简介 SocksPortUnificationServerHandler 自定义PortUnificationServerHandler 总结 简介 在之前的文章中,我们介绍了在同一个netty ...

  5. Redis内存分析工具之redis-rdb-tools的安装与使用

    操作系统:Centos7    1.redis-rdb-tools工具是用python语言编写的,所以首先需要安装python: 安装: (1)用 wget 下载 python 2.7 并解压( 如果 ...

  6. 如何将Excl内数据导入数据库?

    最近有个Excl表格内的数据需要导入SQL Server数据库内,使用SQL Server Management Studio客户端图形界面操作了一番,步骤还挺多,感觉有必要分享给大家一下,顺便自己也 ...

  7. host解析

    首先了解一下什么是hosts文件: hosts是一个没有扩展名的系统文件,可以用记事本等文本编辑工具打开,起作用就是将一些常用的"网址域名"与其对应的"IP地址" ...

  8. 一文搞清楚 DNS 的来龙去脉

    目录 美国霸权 ICANN:互联网界的联合国 IP 地址分配 域名解析架构 分层架构: DNS 缓存: 根 DNS 服务器: 顶级 DNS 服务器(TLD): 权威 DNS 服务器: 本地 DNS: ...

  9. leetcode刷题目录

    leetcode刷题目录 1. 两数之和 2. 两数相加 3. 无重复字符的最长子串 4. 寻找两个有序数组的中位数 5. 最长回文子串 6. Z 字形变换 7. 整数反转 8. 字符串转换整数 (a ...

  10. 图片不清晰?Graphics 高质量绘制

    Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; Graphics ...