点击前往 我的博客访问获得更好的阅读体验

注意

  该博客是为了帮助同学学习,并非为了协助同学刷题,请读者保持自觉,请勿做CV工具人。另外为了节省篇幅,代码中不再写明#include,如果遇到我没有声明的函数,那么就是某一个头文件中的函数,读者搜索“c + 函数名字”就能查到相关信息。

题目

  点击查看原题

题目翻译由 @ZYZ友情提供

  OHgg 想要买一个价值c元的电脑,于是他决定去公司打工赚钱。

  在这个公司中一共有n种职位,并且这些职位的等级被命名为从 1 开始的整数。一位职位等级i的员工一天可以赚a[i]元。职位等级所代表的数值越高,取得的报酬就会越高。最初, OHgg 的职业等级为 1,并且他有 0 元。

  每天 OHgg 都可做以下两件事中的任何一个:

  • 如果 OHgg 此时的职业等级为x,那么他就可以赚取 a[x] 元。
  • 如果 OHgg 此时的职业等级为x(x < n) ,并且他手头至少有 b[x] 元,那么他就可以花费 b[x] 元,通过学习网上课程然后职业等级升值到x + 1

  例如,如果n = 4, c= 15, a = [1 ,3 ,10 ,11],b=[1 ,2 ,7]n=4,c=15,a=[1,3,10,11],b=[1,2,7] , OHgg 可以这样做:

  1. 第一天, OHgg 待在 1 号位置,然后选择赚取 1 元,现在他有 1 元。
  2. 第二天, OHgg 待在 1 号位置,然后选择升值到 2 号位置,现在他有 0 元。
  3. 第三天, OHgg 在 2 号位置,他选择赚取 3 元,此时他有 3 元。
  4. 第四天, OHgg 在 2 号位置,他选择升值到 3 号位置,现在他有 1 元。
  5. 第五天, OHgg 在 3 号位置,他选择赚取 10 元,此时他有 11 元。
  6. 第六天, OHgg 在 3 号位置,他选择赚取 10 元,此时他有 21 元。

  她一共花费了 6 天,然后可以买一台自己想要的电脑。

  所以你的任务是帮助 OHgg 知道最少需要几天才能买到电脑。

输入格式

  第一行有一个整数t,然后有t个样例。

  每个样例第一行有两个整数nc(2 ≤ 105, 1 ≤ 109),nc分别为职位的个数,以及电脑费用。

  第二行是n个整数,a[1] ≤ a[2] ≤ … ≤ a[n] ( 1 ≤ a[i] ≤ 109)

  第三行是n - 1个整数,b[1]、b[2]、b[3]……b[n-1](1 ≤ b[i] ≤ 109)

  (保证所有样例的n的总和不会超过 2×105)

输出格式

  对于每个样例,输出 OHgg 要想买到心仪的电脑至少需要几天。

样例输入

3
4 15
1 3 10 11
1 2 7
4 100
1 5 10 50
3 14 12
2 1000000000
1 1
1

样例输出

6
13
1000000000

题解

  这种题贪心肯定是不可以的,因为很明显如果使用贪心那么我们永远不会选择升级。那么剩下的选择就是DP或者搜索了,DP没有搜索好写,所以我们先来考虑使用搜索。

  使用搜索那么无非就是DFS、BFS,emm,好像两种都可以,我们两种代码都给出来,读者自行查阅吧。

BFS

struct info {int step;int money;int level;info(int a, int b, int c) : step(a), money(b), level(c) {}
};int profit[200000];
int upgrade[200000];
int n;int task(int dist) {queue<info> record;record.emplace(0, 0, 0);int ans = INT_MAX;do {info now = record.front();record.pop();if (now.step >= ans) continue;if (now.money >= dist) {ans = min(ans, now.step);continue;}if (now.money >= upgrade[now.level]) {record.emplace(now.step + 1, now.money - upgrade[now.level], now.level + 1);int dif = dist - now.money;int step = dif / profit[now.level];if (dif % profit[now.level] != 0) ++step;ans = min(ans, now.step + step);} else {int target = min(dist, upgrade[now.level]);int dif = target - now.money;int step = dif / profit[now.level];if (dif % profit[now.level] != 0) ++step;record.emplace(step + now.step, now.money + step * profit[now.level], now.level);}} while (!record.empty());return ans;
}int main() {int t, dist;cin >> t;while (t--) {scanf("%d %d", &n, &dist);for (int i = 0; i != n; ++i) scanf("%d", &profit[i]);for (int i = 0; i != n - 1; ++i) scanf("%d", &upgrade[i]);upgrade[n - 1] = INT_MAX;printf("%d\n", task(dist));}return 0;
}

DFS

struct info {int step;int money;int level;info(int a, int b, int c) : step(a), money(b), level(c) {}
};int profit[200000];
int upgrade[200000];
int n;int task(int dist) {stack<info> record;record.emplace(0, 0, 0);int ans = INT_MAX;do {info now = record.top();record.pop();if (now.step >= ans) continue;if (now.money >= dist) {ans = min(ans, now.step);continue;}if (now.money >= upgrade[now.level]) {record.emplace(now.step + 1, now.money - upgrade[now.level], now.level + 1);int dif = dist - now.money;int step = dif / profit[now.level];if (dif % profit[now.level] != 0) ++step;ans = min(ans, now.step + step);} else {int target = min(dist, upgrade[now.level]);int dif = target - now.money;int step = dif / profit[now.level];if (dif % profit[now.level] != 0) ++step;record.emplace(step + now.step, now.money + step * profit[now.level], now.level);}} while (!record.empty());return ans;
}int main() {int t, dist;cin >> t;while (t--) {scanf("%d %d", &n, &dist);for (int i = 0; i != n; ++i) scanf("%d", &profit[i]);for (int i = 0; i != n - 1; ++i) scanf("%d", &upgrade[i]);upgrade[n - 1] = INT_MAX;printf("%d\n", task(dist));}return 0;
}

  main里面写了一句upgrade[n - 1] = INT_MAX是将最后一级的升级花费设为最大,这样子搜索的时候就不用处理无法升级的情况了,因为最后一级升级的花费太大了。

  代码没有采用一步一步模拟的情况,因为在次数多的时候一步一步模拟必然会超时,所以我们一次性计算出当前步骤的结果即可。

  对于每一步我们都有两种选择:

  • 不升级,获取当前奖励
  • 升级,花费指定数量的钱

  如果我们的钱不够升级那么我们就只剩一种选择,现在我们来说一说怎么省掉中间的模拟步骤的。

  首先,如果我们的钱够升级,那么我们就要从两种选择里面选出一个,如果我们选择升级,那么升级后继续模拟即可;如果我们选择不升级,不难看出我们要一直保持不升级这个策略,如果后面再选择升级和在这里选择升级是一样的。

  其次,对于我们的钱不够升级的情况,我们不能向前面那样直接计算到结束。因为我们后面可能会采取升级的选择,所以我们应当设置一个短期目标,这个短期目标是总体目标和下一次升级所需要的钱中的最小值。

  这样,问题就迎刃而解了(仔细想一下这么写出来的BFS好像也不是完全的BFS了{% inlineimage https://image.kmar.top/icon/bili/guilian.png %})。

[CF1512F] Education题解相关推荐

  1. cf1512F. Education

    cf1512F. Education 题意: 小明想买一个价值为c的东西,他开始打工,他一开始在第i个职务,每天可以挣a[i],他也可以用一天的时间并且花费b[i]升到i+1职务,第i+1职务每天可以 ...

  2. [JS][dfs]题解 | #迷宫问题#

    题解 | #迷宫问题# 题目链接 迷宫问题 题目描述 定义一个二维数组 N*M ,如 5 × 5 数组下所示: int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 1, 1 ...

  3. [JS][dp]题解 | #打家劫舍(一)#

    题解 | #打家劫舍(一)# 题目链接 打家劫舍(一) 题目描述 描述 你是一个经验丰富的小偷,准备偷沿街的一排房间,每个房间都存有一定的现金,为了防止被发现,你不能偷相邻的两家,即,如果偷了第一家, ...

  4. [JS]题解 | #魔法数字#

    题解 | #魔法数字# 题目链接 魔法数字 题目描述 牛妹给牛牛写了一个数字n,然后又给自己写了一个数字m,她希望牛牛能执行最少的操作将他的数字转化成自己的. 操作共有三种,如下: 在当前数字的基础上 ...

  5. [JS]题解 | #岛屿数量#

    题解 | #岛屿数量# 题目链接 岛屿数量 题目描述 时间限制:1秒 空间限制:256M 描述 给一个01矩阵,1代表是陆地,0代表海洋, 如果两个1相邻,那么这两个1属于同一个岛.我们只考虑上下左右 ...

  6. [JS] 题解:提取不重复的整数

    题解:提取不重复的整数 https://www.nowcoder.com/practice/253986e66d114d378ae8de2e6c4577c1 时间限制:1秒 空间限制:32M 描述 输 ...

  7. 洛谷-题解 P2672 【推销员】

    独门思路!链表加优先队列! 这题一望,贪心是跑不掉了,但是我贪心并不好,所以想到了一个复杂一些但思路更保稳的做法 思路: 1 因为是离线操作,所以我们可以倒着求,先求x=n的情况,因为那样直接就知道了 ...

  8. [洛谷1383]高级打字机 题解

    题解 这道题一看就珂以用主席树啊 这是一道神奇的题目,那么我们先敲一个主席树,然后维护一个数组len,表示下一次应该在len + 1插入, 之后对于T操作,在上一个版本的len + 1上直接执行插入 ...

  9. luogu P1549 棋盘问题(2) 题解

    luogu P1549 棋盘问题(2) 题解 题目描述 在\(N * N\)的棋盘上\((1≤N≤10)\),填入\(1,2,-,N^2\)共\(N^2\)个数,使得任意两个相邻的数之和为素数. 例如 ...

最新文章

  1. php ×××号码效验码生成函数
  2. iOS开发中接口调用使用https
  3. RabbitMQ分布式集群架构
  4. Stanford UFLDL教程 用反向传导思想求导
  5. idea maven创建java项目_新版本IntelliJ IDEA 构建maven,并用Maven创建一个web项目(图文教程)...
  6. 开心的金明(洛谷-P1060)
  7. phpSysInfo监测服务器
  8. Concepts in Games Development(游戏开发概述) 公开课笔记
  9. RESTFfu l规范 以及理解
  10. (继续搬)struts日期格式的转换以及hibernate中session的关闭在xml中的配置
  11. UVA10946 You want what filled?【DFS】
  12. python int_Python int()
  13. 【数学优化】学习知识点
  14. 360与Bing合作上线英文搜索
  15. php悲观锁怎么做,mysql悲观锁怎么实现?
  16. linux终端下打开pdf文件,如何从终端打开PDF文件?
  17. 从平面坐标转球面坐标加旋转
  18. 1995-2013年RSA大会历届主题回顾
  19. MSDC 4.3 接口规范(21)
  20. 推荐画UML图以及流程图的在线网站Site

热门文章

  1. druid监控页面 关闭_阿里Druid监控页面分析
  2. 微信小程序:保持常亮
  3. Java中如何唤醒一个阻塞的线程?
  4. 解决go包管理代理网址无法访问:proxy.golang.org
  5. 【OneNote 小技巧】——利用OneNote进行录音和录像
  6. Stacking集成学习算法
  7. 02. 【Java】语言编程基础
  8. 题解记录-BUUCTF|Web (持续更新中)
  9. linux如何挂载硬盘linux服务器上挂载磁盘(图文详解)
  10. 程序员用12小时复刻《羊了个羊》,代码已开源!