CF1989D Smithing Skill 题解
这篇题解是我在赛场上的真实思路,所以可能会比较冗长。但是相较于其他题解,读者可以在这篇题解中理解为什么会想到使用动态规划。我认为,授人以鱼不如授人以渔,理解为什么想到使用动态规划,比知道使用动态规划更重要。
首先,有一个比较显然的贪心。每次合成之后立即融掉,可以获得 \(2\) 点技能点,并失去材料 \(a_i-b_i\) 个。因此,我们把所有合成方式按照 \(a_i-b_i\) 升序排序,先合成消耗少的合成方式,再合成消耗多的合成方式。
考虑到需要 \(a_i\) 个材料才能合成,若 \(a_i-b_i\) 相等,我们采用 \(a_i\) 较小的合成方式,这样就可以合成更多次。不难发现如果一种合成方式 \(a_i-b_i\) 大于等于其他合成方式,并且 \(a_i\) 大于等于其他合成方式,这种合成方式一定不优,可以舍去。于是,现在的合成方式序列满足若 \(i\lt j\),则 \(a_i-b_i\lt a_j-b_j\) 且 \(a_i\gt a_j\)。对于某种数量 \(c\),最优的合成方式显然是满足 \(a_i\le c\) 的编号最小的位置。
每种材料互相独立,分别处理。首先考虑如何使用最优的一种合成方式进行合成。我们先留下 \(a_i\) 个材料,并对于剩下的材料进行合成,每次消耗 \(a_i-b_i\) 个,利用除法直接算出。这样就保证了至少有 \(a_i\) 个材料,一定可以合成。之后,我们求出合成后的余数,加到留下的 \(a_i\) 个中,然后暴力计算。显然,这个计算的次数不会太多,大概 \(0\sim1\) 次,可以看作常数。
根据数据范围,使用最优的一种合成方式进行合成后,剩余的材料数量不会超过 \(10^6\),考虑预处理。设 \(f[i]\) 表示剩余 \(i\) 个材料可以合成并融化的最多次数,我们发现,无论对于哪一个 \(i\),进行一部分操作之后,\(i\) 只会变小而不会变大。也就是说,如果从小到大枚举 \(i\),\(f[i]\) 的求解仅依赖于之前的状态,可以动态规划。
从小到大枚举 \(i\),我们发现,经过第一步的处理后,可以使用的最优的一种合成方式也在从编号大到编号小单调递减,可以直接维护。使用最优的一种合成方式进行合成,就可以直接将剩余的材料数量可以合成并融化的最多次数通过状态累加过来。于是,我们就在线性时间内预处理出了 \(f[i]\)。
最后,思维变得很明朗。如果 \(c\le10^6\),直接查表得到 \(f[c]\)。否则,使用最优的一种合成方式进行合成后,再查表累加进答案。
使用桶排序,时间复杂度为 \(O(n)\),非常优秀。
#include <bits/stdc++.h>
using namespace std;
long long t,n,m,c,a[1500000],b[1500000],s[1500000],q[1500000],p[1500000],f[1500000],cnt=0,now=0,ans=0;
inline long long read()
{
long long x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
return x*f;
}
int main()
{
for(int i=0;i<=1000000;i++)s[i]=1e9;
n=read(),m=read();
for(int i=1;i<=n;i++)a[i]=read();
for(int i=1;i<=n;i++)b[i]=read();
for(int i=1;i<=n;i++)s[a[i]-b[i]]=min(s[a[i]-b[i]],a[i]);
cnt=0,q[cnt]=1e9,p[cnt]=0;
for(int i=1;i<=1000000;i++)
if(s[i]<q[cnt])q[++cnt]=s[i],p[cnt]=i;
now=cnt;
for(int i=1;i<=1000000;i++)
{
while(q[now]<=i&&now>0)now--;
if(now<cnt)now++;
else continue;
c=i,f[i]+=(c-q[now])/p[now];
c=(c-q[now])%p[now]+q[now];
while(c>=q[now])c-=p[now],f[i]++;
f[i]+=f[c];
}
for(int i=1;i<=m;i++)
{
c=read();
if(c<q[1])
{
ans+=f[c];
continue;
}
ans+=(c-q[1])/p[1];
c=(c-q[1])%p[1]+q[1];
while(c>=q[1])c-=p[1],ans++;
ans+=f[c];
}
printf("%lld\n",ans*2);
return 0;
}
CF1989D Smithing Skill 题解的更多相关文章
- [模拟赛FJOI Easy Round #2][T3 skill] (最小割+最大权闭合子图(文理分科模型))
[题目描述] 天上红绯在游戏中扮演敏剑,对于高攻击低防御的职业来说,爆发力显得非常重要,为此,她准备学习n个技能,每个技能都有2个学习方向:物理攻击和魔法攻击.对于第i个技能,如果选择物理攻击方向,会 ...
- AtCoder Beginner Contest 089完整题解
A - Grouping 2 Time limit : 2sec / Memory limit : 256MB Score : 100 points Problem Statement There a ...
- HDU 4352 XHXJ's LIS HDU 题解
题目 #define xhxj (Xin Hang senior sister(学姐)) If you do not know xhxj, then carefully reading the ent ...
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
- noip2016十连测题解
以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...
- BZOJ-2561-最小生成树 题解(最小割)
2561: 最小生成树(题解) Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1628 Solved: 786 传送门:http://www.lyd ...
- Codeforces Round #353 (Div. 2) ABCDE 题解 python
Problems # Name A Infinite Sequence standard input/output 1 s, 256 MB x3509 B Restoring P ...
- 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解
题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...
- 2016ACM青岛区域赛题解
A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ...
- 【转】What is an SDET? Part 2 – Skill Matrix of SDET
What is an SDET? Part 2 ---- Skill Matrix of SDET (Instead of naming it as part 2 of What is an SDET ...
随机推荐
- 基于Lighthouse搭建高颜值的YesPlayMusic网易云播放器
本文介绍了如何使用腾讯云的Lighthouse轻量应用服务器来搭建一个高颜值的第三方网易云播放器. 项目简介 本文使用的是YesPlayMusic项目,这是一款高颜值的第三方网易云播放器,它完全可以作 ...
- emmy断点调试
package.cpath = package.cpath .. ';C:/Users/Administrator/AppData/Roaming/JetBrains/IntelliJIdea2021 ...
- 使用Python+SymPy求解微分方程
引言 在学习微积分或者物理.工程相关的学科时,微分方程常常是我们需要解决的一个重要问题.微分方程是包含未知函数及其导数的方程,广泛应用于描述变化过程中的规律,如物理中的运动方程.化学中的反应速率.经济 ...
- Launchpool名词解释
# 一.什么是Launchpool Launchpool是一种加密货币领域的创新机制,通常由交易所或DeFi平台提供,允许用户通过质押(staking)或锁定特定代币来获得新项目的代币奖励. ## L ...
- Python3工具_C段扫描工具_主机存活探测初始
之前搞了多线程 然后基于多线程写了个C段主机存活探测工具 扫描主函数 def sub(): global num num=0 while not q.empty(): threadLock.acqui ...
- TypeScript+Vue3
TypeScript Any 类型 和 unknown 顶级类型 1.没有强制限定哪种类型,随时切换类型都可以 我们可以对 any 进行任何操作,不需要检查类型 2.声明变量的时候没有指定任意类型默认 ...
- AutoCAD AutoLISP 中使用 entmake 创建标注样式(DIMSTYLE)的深度解析
前言 在 AutoCAD 二次开发中,entmake 函数相比 command 命令具有三大核心优势: 高效性:直接操作图形数据库,避免交互式命令延迟 稳定性:消除命令行参数解析导致的不可控错误 精确 ...
- RPC实战与核心原理之时钟轮
时钟轮在RPC中的应用 回顾 在分布式环境下,RPC 框架自身以及服务提供方的业务逻辑实现,都应该对异常进行合理地封装,让使用方可以根据异常快速地定位问题:而在依赖关系复杂且涉及多个部门合作的分布式系 ...
- Go Gob编码
gob(Go binary)是Goland包自带的一个数据结构序列化的编码/解码工具.编码使用Encoder,解码使用Decoder.一种典型的应用场景就是RPC(remote procedure c ...
- vivo官网APP首页端智能业务实践
作者:vivo 互联网客户端团队- Li Quanlong 本文介绍端智能技术在vivo官网APP的落地实践,通过抽象问题.提出端智能解决方案.方案落地这三大块内容逐步递进地展开端智能技术的应用过程. ...