【题解】小奇挖矿

题目描述

小奇要开采一些矿物,它驾驶着一台带有钻头(初始能力值 \(w\))的飞船,按既定路线依次飞过喵星系的 \(n\) 个星球。

星球分为 \(2\) 类:资源型和维修型。

  1. 资源型:含矿物质量 \(a_i\),若选择开采,则得到 \(a_i\times p\) 的金钱,之后钻头损耗 \(k\%\),即 \(p\leftarrow p\times (1-k\%)\)
  2. 维修型:维护费用 \(b_i\),若选择维修,则支付 \(b_i\times p\) 的金钱,之后钻头修复 \(c\%\),即 \(p\leftarrow p\times (1+c\%)\)

(\(p\) 为钻头当前能力值)

注:维修后钻头的能力值可以超过初始值。

请你帮它决策最大化这个收入。

输入格式

第一行 \(4\) 个整数 \(n\),\(k\),\(c\),\(w\)。

以下 \(n\) 行,每行 \(2\) 个整数 \(type\),\(x\):

  • \(type\) 为 \(1\) 则代表其为资源型星球,\(x\) 为其矿物质含量 \(a_i\);
  • \(type\) 为 \(2\) 则代表其为维修型星球,\(x\) 为其维护费用 \(b_i\)。

输出格式

输出一行一个实数 (保留两位小数),表示要求的结果。

数据范围

测试时间限制 \(1000 \textrm{ms}\),空间限制 \(256 \textrm{MiB}\)。

  • 对于 \(30\%\) 的数据 \(n\le 100\)
  • 对于 \(50\%\) 的数据 \(n\le 1000\),\(k=100\)
  • 对于 \(100\%\) 的数据 \(n\le 10^5\),\(0\le k,c,w,a_i,b_i\le 100\)

保证答案不超过 \(10^9\)。

分析

这道题的部分分设计不当,我们来考虑一下 Author 为什么这么设部分分。

\(30\; \mathtt{pts}\)

注意到这题的钻头和金钱是两个变量,我们一定要控制一个。但是都是实数不好表示。怎么办?

再次注意到这题的钻头耐久机制是乘法。由于乘法满足交换律和结合律,所以我们只要记录下开了几次矿,修了几次就行了。

定义 \(f_{i,j,k}\) 为修理 \(i\) 次,开矿 \(j\) 次,目前已经到达第 \(k\) 个星球的最大金钱数。

递推也好得到:\(f_{i,j,k}=\begin{cases}\max\{f_{i,j,k-1},f_{i,j-1,k-1}+a_i\times calc(i,j-1)\}&k\;\text{号星球是资源型}\\\max\{f_{i,j,k-1},f_{i-1,j,k-1}-b_i\times calc(i-1,j)\}&k\;\text{号星球是修理型}\end{cases}\)。

边界值:\(f_{0,0,0}=0\),其余赋值 \(-\infty\)。最终求 \(\max\{f_{i,j,n}\}\)。

复杂度 \(\Theta(n^3)\)。

是不是已经有点不明所以,不知道如何优化了?接下来就会更加令人疑惑了。

\(50\;\mathtt{pts}\)

这是福利的部分分,却是 AC 的坑。

我们来看一下这 \(50\%\) 的数据。最引人注目的就是那个闪闪发光的——
\[
\Huge\color{lightblue}{k=100}
\]

好了这波福利部分分应该怎么拿呢?

考虑到这是用乘法进行计算,并且只要挖一次,钻头就会彻底报废。

那么我们只要枚举修理的次数就可以了。复杂度可以降到 \(\Theta(n^2)\)。

\(100\;\mathtt{pts}\)

完了,现在没有福利保障了,\(n\) 的范围也大增,怎么搞呢?

如果你有被部分分骗了的感觉,那你就能感受到此题 Author 的丑恶。

我们回过头去想最开始的那个 DP。

记得不?那个 \(\Theta(n^3)\) 的 DP。

这个复杂度为什么这么高?因为有钻头的变量在影响着我们。

那么,我们要做一个大胆的操作,那就是把钻头的影响消除。

这个怎么搞呢?我们来想一想:

下面为了方便考虑,我们定义数列 \({c_i}=\begin{cases}a_i&i\;\text{号星球是资源型}\\-b_i&i\;\text{号星球是维修型}\end{cases}\);

\(u_i=\begin{cases}1-k\%&i\;\text{号星球是资源型}\\1+c\%&i\;\text{号星球是维修型}\end{cases}\);

\(r_i=\text{最优解是否选择第 }i\text{ 个。选了就是 }1\text{,否则就是 }\dfrac{1}{u_i}\)。



假设在最优解的情况下,经过第 \(i\) 个星球后,钻头的耐久成为了 \(w_i\)。

那么总共的钱数 \(M=\sum^n_{i=1}(w_i\times c_i)\)

而对于 \(w_i=w\times \prod^i_{j=1}(u_j\times r_j)\)

注意到只有 \(r_i\) 是不确定的。而不确定的 \(r_i\) 只会影响 \(w_k(1\le k\le i)\)。

也就是说,任意一个星球的决策不会影响后面所有的决策

本着 DP 没有后效性的原则,我们自然而然想出了一个操作,那就是——
\[
\Huge{\text{从后往前做 DP}}
\]



好了,现在正解已经呼之欲出了。

定义 \(f_i\) 为 \(i\) 个星球的金钱最大值。

我们只需要假定当前钻头耐久为 \(1\),完成这一轮决策后再把这一轮的钻头初始耐久设为 \(1\)。

如此这般,最后再乘上 \(w\),就是答案。

当然,我们可以把 \(f_i\) 浓缩成一个数,节省空间。

Code

日常放代码。虽然这一次的题目已经没有什么代码难度了。

#include <cstdio>
#include <cctype>
using namespace std;

constexpr int max_n = 100000;
double val[max_n];
bool is_fix[max_n];

inline int read()
{
    int ch = getchar(), n = 0, t = 1;
    while (isspace(ch)) { ch = getchar(); }
    if (ch == '-') { t = -1, ch = getchar(); }
    while (isdigit(ch)) { n = n * 10 + ch - '0', ch = getchar(); }
    return n * t;
}

inline double my_max(double x, double y) { return (x > y)? x:y; }

int main()
{
    int n = read(), cost = read(), exp = read(), wei = read(), type, tmp;
    double ans = 0;

    for (int i = 0; i < n; i++)
    {
        scanf("%d%d", &type, &tmp);

        val[i] = tmp;
        is_fix[i] = (type == 2);
    }

    for (int i = n - 1; i >= 0; i--)
    {
        if (is_fix[i])
            ans = my_max(ans, ans * (1 + exp / 100.0) - val[i]);
        else
            ans = my_max(ans, ans * (1 - cost / 100.0) + val[i]);
    }

    printf("%.2lf\n", ans * wei);

    return 0;
}

后记

我考场上时也没有想到正解。虽然朦朦胧胧知道要利用乘法这个性质。

后来看到 solution 时真是自愧不如。

又过了一阵子,我好不容易脑补出来这么一个想法的过程。自我感觉讲得很清楚。

如果这篇题解对你有帮助,欢迎点赞、留言,给 5ab 提出意见。感谢大家的资瓷哦!

原文地址:https://www.cnblogs.com/5ab-juruo/p/solution-20200221-explo.html

时间: 2024-11-02 03:04:35

【题解】小奇挖矿的相关文章

4711: 小奇挖矿

4711: 小奇挖矿 Description [题目背景] 小奇在喵星系使用了无限非概率驱动的采矿机,以至于在所有星球上都采出了一些矿石,现在它准备建一些矿石仓 库并把矿石运到各个仓库里. [问题描述] 喵星系有n个星球,标号为1到n,星球以及星球间的航线形成一棵树.所有星球间的双向航线的长度都为1.小奇要 在若干个星球建矿石仓库,设立每个仓库的费用为K.对于未设立矿石仓库的星球,设其到一个仓库的距离为i,则 将矿石运回的费用为Di.请你帮它决策最小化费用. Input 第一行2个整数n,K.

【NOIP模拟赛】小奇挖矿 2

[题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿石交易市场,以便为飞船升级无限非概率引擎. [问题描述] 现在有m+1个星球,从左到右标号为0到m,小奇最初在0号星球. 有n处矿体,第i处矿体有ai单位原矿,在第bi个星球上. 由于飞船使用的是老式的跳跃引擎,每次它只能从第x号星球移动到第x+4号星球或x+7号星球.每到一个星球,小奇会采走该星球上所有的原矿,求小奇能采到的最大原矿数量. 注意,小奇不必最终到达m号星球. [输入格式] 第一行2个整数n,m

【BZOJ4548】小奇的糖果 set(链表)+树状数组

[BZOJ4548]小奇的糖果 Description 有 N 个彩色糖果在平面上.小奇想在平面上取一条水平的线段,并拾起它上方或下方的所有糖果.求出最多能够拾起多少糖果,使得获得的糖果并不包含所有的颜色. Input 包含多组测试数据,第一行输入一个正整数 T 表示测试数据组数. 接下来 T 组测试数据,对于每组测试数据,第一行输入两个正整数 N.K,分别表示点数和颜色数. 接下来 N 行,每行描述一个点,前两个数 x, y (|x|, |y| ≤ 2^30 - 1) 描述点的位置,最后一个数

[BZOJ4548]小奇的糖果

[BZOJ4548]小奇的糖果 试题描述 有 \(N\) 个彩色糖果在平面上.小奇想在平面上取一条水平的线段,并拾起它上方或下方的所有糖果.求出最多能够拾起多少糖果,使得获得的糖果并不包含所有的颜色. 输入 包含多组测试数据,第一行输入一个正整数 \(T\) 表示测试数据组数. 接下来 \(T\) 组测试数据,对于每组测试数据,第一行输入两个正整数 \(N\).\(K\),分别表示点数和颜色数. 接下来 \(N\) 行,每行描述一个点,前两个数 \(x, y (|x|, |y| \le 2^{3

换根dp「小奇的仓库&#183;randomwalking&#183;」

把以前考试换根题集中写一下 随便选一个点做根一遍$dfs$求子树内贡献,再通过特殊手段算$ans[1]$,最后$dfs$求其他$ans$ 拆成子树内,子树外分别算贡献差,得儿子是很常见套路了 小奇的仓库 $M<=15$ 题解 很久之前做的换根dp,当时觉得真是神仙,现在看还是觉得很神仙 不同于一般换根dp,这个题$n^2$并不好写 所以$n^2$算法就省略了 考虑$M$非常小,可以计算$M$对答案影响 一个直接的想法是先算出来原答案,再减去现在答案 //本来为j现在异或M,变化了j-delta

【BZOJ-4548&amp;3658】小奇的糖果&amp;Jabberwocky 双向链表 + 树状数组

4548: 小奇的糖果 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 103  Solved: 47[Submit][Status][Discuss] Description 有 N 个彩色糖果在平面上.小奇想在平面上取一条水平的线段,并拾起它上方或下方的所有糖果.求出最多能够拾 起多少糖果,使得获得的糖果并不包含所有的颜色. Input 包含多组测试数据,第一行输入一个正整数 T 表示测试数据组数. 接下来 T 组测试数据,对于每组测试数据,第

小奇的仓库

题目来源:hzwer [题目背景] 小奇采的矿实在太多了,它准备在喵星系建个矿石仓库.令它无语的是,喵星系的货运飞船引擎还停留在上元时代! [问题描述] 喵星系有n个星球,星球以及星球间的航线形成一棵树. 从星球a到星球b要花费[dis(a,b) Xor M]秒.(dis(a,b)表示ab间的航线长度,Xor为位运算中的异或) 为了给仓库选址,小奇想知道,星球i(1<=i<=n)到其它所有星球花费的时间之和. [输入格式] 第一行包含两个正整数n,M.接下来n-1行,每行3个正整数a,b,c,

小奇的花园

[问题描述]小奇的花园有 n 个温室,标号为 1 到 n,温室以及以及温室间的双向道路形成一棵树.每个温室都种植着一种花,随着季节的变换,温室里的花的种类也在不断发生着变化.小奇想知道从温室 x 走到温室 y 的路径中(包括两个端点),第 t 种花出现的次数.[输入格式]第一行为两个整数 n,q,表示温室的数目和操作的数目.第二行有 n 个整数 T 1 ,T 2 ...T n 其中 T i 表示温室 i 中的花的种类.接下来 n-1 行,每个两个整数 x, y,表示温室 x 和 y 之间有一条双

【OJ2216】小奇的数列

2216 -- 小奇的数列(Solution) 题目大意 : 给定一个长度为?\(n\)?的数列,以及?\(m\)?次询问,每次给出三个数?\(l\),\(r\)?和?\(P\),询问 \((\sum_{i=l_1}^{r_1}a_i)\;mod\;P\)?的最小值. 其中 \(l \le l_1 \le r_1 \le r\) . \((n\le 5\times 10^5, m\le 10^4,P\le 500)\) Tag: 抽屉原理.STL Analysis By LC: 最朴素的做法当然