当前位置: 首页 > news >正文

信息学奥赛一本通 ybt 1940:【07NOIP普及组】守望者的逃离 | 洛谷 P1095 [NOIP 2007 普及组] 守望者的逃离

【题目链接】

ybt 1940:【07NOIP普及组】守望者的逃离
洛谷 P1095 [NOIP 2007 普及组] 守望者的逃离

【题目难度】:B

【题目考点】

1. 动态规划
2. 贪心

【解题思路】

非正解解法:搜索

每步尝试进行等待、闪烁、跑步三种行动,搜索所有可能的行动方案。
如果存在移动距离大于等于s的情况,则记录该情况使用的时间。
同时维护使用时间为t时移动的最大距离。最后输出结果。
该方法可以得30分。

正解解法:动态规划

现在考虑以下两种走法:

  1. 等待恢复魔法,有足够魔法就使用闪烁
  2. 一直跑步

首先假设时间无限长,使用哪种走法更合适。
每秒恢复魔法4点,每次闪烁消耗魔法10点,如果仅靠恢复的魔法进行闪烁,且有魔法就是闪烁,那么守望者的行动顺序为:

时刻(第几秒)操作操作后剩余魔法移动动距离
1休息40
2休息80
3休息120
4闪烁260
5休息660
6休息1060
7闪烁0120

根据上表可知,守望者完全靠休息恢复魔法和闪烁技能,每7秒钟可以前进120米。
而如果每秒都跑步,7秒可以前进7∗17=1197*17=119717=119米,比休息+闪烁的前进方案前进距离更短。
因此,如果时间足够长,需要走的距离足够远,应该尽量使用休息+闪烁的方案前进。
而如果已经接近终点,比如此时距离终点20米,但魔法值为0。如果想使用闪烁,需要休息3秒后再闪烁,需要4秒才能到达终点。而如果跑步,2秒后就可以到达终点。因此当距离较短时,应该跑步前进。
基于上述理解,可以预处理出数组ffffif_ifi表示前iii秒只进行休息+闪烁可以前进的最大距离。
设变量mmm表示守望者的剩余魔法值。在第iii秒时:

  • 如果m≥10m\ge 10m10,那么可以使用闪烁,就使用。第iii秒移动的距离比第i−1i-1i1秒增加60,即fi=fi−1+60f_i = f_{i-1}+60fi=fi1+60,同时剩余魔法值mmm减少10。
  • 如果m<10m < 10m<10,那么只能休息,第i秒移动的距离与第i−1i-1i1秒移动距离相同,即fi=fi−1f_i = f_{i-1}fi=fi1,同时剩余魔法值mmm增加10。

设动规状态定义dpdpdpdpidp_idpi表示前iii秒进行的所有行动方案中,前进距离最大的方案的前进距离。即前i秒可以前进的最大距离。
初值dp0=0dp_0 = 0dp0=0
分析状态转移方程:根据第i秒是否跑步分割策略集合。

  • 情况1:在前i−1i-1i1秒前进距离最大的方案基础上,在第iii秒跑步前进,这样做前iii秒可以行进的距离为dpi−1+17dp_{i-1}+17dpi1+17
  • 情况2:由于跑步前进可能不如休息+闪烁移动的距离更大,因此前iii秒也可以选择只进行休息+闪烁的行动方案,前iii秒的行进距离为fif_ifi
  • 两种情况取最大值。

因此:dpi=max⁡{dpi−1+17,fi}dp_i = \max\{dp_{i-1}+17, f_i\}dpi=max{dpi1+17,fi}
递推求出dpdpdp数组的同时,看前iii秒守望者移动的最大距离dpidp_idpi是否大于等于总距离sss。如果dpi≥sdp_i\ge sdpis,那么守望者只需要iii秒时间就可以逃出洞窟,输出Yes和iii,程序结束。
递推结束后,如果程序没有结束,那么守望者在ttt秒时间内无法逃出。ttt秒时间守望者可以前进的最大距离为dptdp_tdpt,输出No和dptdp_tdpt

递推变迭代

由于在递推求fffdpdpdp的递推式中,只存在第i−1i-1i1项的值fi−1f_{i-1}fi1dpi−1dp_{i-1}dpi1,因此可以降维,变递推为迭代。
比如将f[i] = f[i-1]+60变为f = f+60。等号右边的f表示f[i-1],等号左边的f表示f[i]
这样依然可以正确求出结果,并且可以优化代码的空间复杂度。但变量的意义、整个算法的概念没有变。

【题解代码】

非正解解法1:搜索 30pt
#include <bits/stdc++.h>
using namespace std;
int m, s, t, ansTime = 1e9, ansDis;
bool hasAns;
void dfs(int time, int ma, int dis)//走了time秒时间,剩余魔法ma,已走距离dis 
{if(dis >= s){hasAns = true;ansTime = min(time, ansTime);return; }if(time == t){ansDis = max(ansDis, dis);return;}dfs(time+1, ma+4, dis);//休息if(ma >= 10)dfs(time+1, ma-10, dis+60);//闪烁dfs(time+1, ma, dis+17);//跑步 
}
int main()
{cin >> m >> s >> t;dfs(0, m, 0);if(hasAns)cout << "Yes\n" << ansTime;elsecout << "No\n" << ansDis;return 0;
}
正解解法:动态规划
  • 写法1:基本写法
#include<bits/stdc++.h>
using namespace std;
#define N 300005
int f[N];//f[i]:前i秒只使用闪烁能走到的最大的距离 
int dp[N];//dp[i]:前i秒能走到的最大的距离
int main()
{int m, s, t;cin >> m >> s >> t;for(int i = 1; i <= t; ++i){if(m >= 10) {f[i] = f[i-1]+60;m -= 10;}else{f[i] = f[i-1];m += 4;}}for(int i = 1; i <= t; ++i){dp[i] = max(f[i], dp[i-1]+17);if(dp[i] >= s){cout << "Yes" << '\n' << i;return 0;}}cout << "No\n" << dp[t];return 0;
}
  • 写法2:递推变迭代
#include<bits/stdc++.h>
using namespace std;
int main()
{int m, s, t, f, dp;//f:前i秒只使用闪烁能走到的最大的距离  dp:前i秒能走到的最大的距离;cin >> m >> s >> t;for(int i = 1; i <= t; ++i){if(m >= 10){f = f+60;m -= 10;}elsem += 4;dp = max(f, dp+17);if(dp >= s){cout << "Yes" << '\n' << i;return 0;}}cout << "No\n" << dp;return 0;
}
http://www.dtcms.com/a/558155.html

相关文章:

  • 淘宝实时优惠券网站怎么做的甘肃建设监理协会网站
  • 工业一体机在UV固化机中的应用
  • 《算法通关指南:数据结构和算法篇 --- 顺序表相关算法题》--- 1.询问学号,2.寄包柜,3.合并两个有序数组
  • 陕西省关于网站信息内容建设南通网站建设企业
  • 【愚公系列】《MCP协议与AI Agent开发》003-大模型原理及MCP开发基础(LLM 的输入输出机制与上下文表示)
  • 国内酒店网站建设厦门房产网
  • 【开题答辩过程】以《基于微信小程序垃圾分类图像识别技术实现》为例,不会开题答辩的可以进来看看
  • 区块链论文速读 CCF A--USENIX Security 2025(3)
  • 美食网站建设策划报告企业开展网络营销方案
  • 和田网站制作南约社区网站建设
  • 江西省住房和城乡建设部网站谷歌seo外链平台
  • 使用 windeployqt 工具自动部署Qt依赖环境(DLL、插件、翻译文件等)
  • RDPWD!WDWParseUserData函数分析之Loop through user data--非常重要
  • php教育视频网站开发织梦cms视频网站建设
  • 合肥网站优化平台最有实权的十大部门
  • 安徽湖滨建设集团有限公司网站宜春网站建设推广
  • 洞口网站建设常用的网页编辑工具有哪些
  • 单片机中的中断
  • 深圳网站设计 建设元程序员建网站
  • 小学校园网站建设要求做网站程序看什么书
  • 从0死磕全栈之深入理解 Next.js 中的 NextResponse:API 详解与实战示例
  • 彩票网站开发制作需要什么php网站接入支付宝
  • 如何做网站聚合页做普工招聘网站
  • LLM之Agent(二十四)| AI Agents上下文工程(Context Engineering)指南
  • 简述网站的四种常见结构网站用的服务器
  • 【大模型训练】zero2 梯度分片
  • 网站权重怎么看百度百科合作模式
  • 英文网站如何推广新手建站论坛
  • 瑞尔特(002790)2025年10月31日涨停分析报告
  • VTK开源视觉库 | 概述