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

洛谷 P12078 [OOI 2025] Best Runner 题解

提示:本篇题解的做法并不具有绝对正确性,仅能通过较弱的测试数据。然而这种卡时的思想具有一定的启发性,例如某些随机化或模拟退火的题目就我们就可以尝试多换几个随机种子,不断运行算法直到即将超时,这样可以有更大的概率得到正确答案。

Solution

首先分析每位跑者的最优决策,尝试寻找一下特殊性质。

首先,直觉告诉我们,在不同跑道间切换的过程中一定不会改变方向。假设最优策略中改变了方向,最终跑过了 \(l\sim r\) 这些跑道。而一开始就直接一步步切换到这其中最短的跑道并在它上面一直跑下去一定不会更劣。

其次,最优策略一定是往一个方向切换若干条跑道后,在最后一条跑道一直跑,且它一定是这些跑道中最短的。用反证法易证:假设最短的不是最后一条,那我们直接提前在最短的那里停下一直跑一定更优。

\(L(i)\) 为第 \(i\) 条跑道左边第一个比它短的跑道下标,\(R(i)\) 同理。根据前面的结论可知,初始时位于跑道 \(i\) 的跑者最终只可能停在 \(i,L(i),L(L(i)),\dots\)\(R(i),R(R(i)),\dots\)

因此我们直接用单调栈预处理出 \(L(i)\)\(R(i)\),再暴力枚举所有可能的位置计算最优的答案。注意用前缀和 \(O(1)\) 计算 \(a_i\) 的区间和。这就有了这份代码:

#include <iostream>
#define rept(i,a,b) for(int i(a);i<=b;++i)
#define pert(i,a,b) for(int i(a);i>=b;--i)
#define int long long  // 注意开long long
using namespace std;
constexpr int N=3e5+5;
int a[N],b[N],s[N],l[N],r[N],stk[N],top;
signed main(){cin.tie(0)->sync_with_stdio(0);int n,m,T,ans=0;cin>>n>>m>>T;rept(i,1,n){cin>>a[i];s[i]=s[i-1]+a[i];}rept(i,1,m){cin>>b[i];}rept(i,1,n){while(top&&a[stk[top]]>=a[i]) --top;l[i]=stk[top];stk[++top]=i;}top=0;pert(i,n,1){while(top&&a[stk[top]]>=a[i]) --top;r[i]=stk[top];stk[++top]=i;}rept(i,1,m){int p=b[i];while(p){ans=max(ans,b[i]-p+(T-s[b[i]]+s[p])/a[p]);p=l[p];}p=b[i];while(p){ans=max(ans,p-b[i]+(T-s[p-1]+s[b[i]-1])/a[p]);p=r[p];}}end:cout<<ans;return 0;
}

这种 \(O(玄学)\) 优雅的暴力在随机数据上表现相当不错,能获得 90 分。然而它卡不过 Subtask 2。

其实构造 Hack 很简单,只要随便搞个单峰序列例如 \(1,2,3,4,3,2,1\) 就能把它卡到 \(O(n^2)\)。但是我们还有最后一招——乱搞。

考虑卡时,在即将 TLE 时输出当前得到的最优解。这种做法大概率是正确的,但取决于数据强度。这样就可以 AC 啦!

AC Code

#include <iostream>
#include <chrono>
#define rept(i,a,b) for(int i(a);i<=b;++i)
#define pert(i,a,b) for(int i(a);i>=b;--i)
#define int long long  // 注意开long long
using namespace std;
constexpr int N=3e5+5;
int a[N],b[N],s[N],l[N],r[N],stk[N],top;
signed main(){cin.tie(0)->sync_with_stdio(0);auto start=chrono::high_resolution_clock::now(); int n,m,T,ans=0;cin>>n>>m>>T;rept(i,1,n){cin>>a[i];s[i]=s[i-1]+a[i];}rept(i,1,m){cin>>b[i];}rept(i,1,n){while(top&&a[stk[top]]>=a[i]) --top;l[i]=stk[top];stk[++top]=i;}top=0;pert(i,n,1){while(top&&a[stk[top]]>=a[i]) --top;r[i]=stk[top];stk[++top]=i;}rept(i,1,m){int p=b[i];while(p){ans=max(ans,b[i]-p+(T-s[b[i]]+s[p])/a[p]);p=l[p];auto stop=chrono::high_resolution_clock::now();  auto ms=std::chrono::duration_cast<std::chrono::milliseconds>(stop-start).count();  if(ms>900) goto end;}p=b[i];while(p){ans=max(ans,p-b[i]+(T-s[p-1]+s[b[i]-1])/a[p]);p=r[p];auto stop=chrono::high_resolution_clock::now();  auto ms=std::chrono::duration_cast<std::chrono::milliseconds>(stop-start).count();  if(ms>900) goto end;}}end:cout<<ans;return 0;
}

完结撒花 ★,°:.☆( ̄▽ ̄)/$:.°★ !!!

http://www.wooajung.com/news/35398.html

相关文章:

  • 远程git ssh配置1
  • 7月24日总结
  • VIRTUBOX BUG
  • 精通Python PDF裁剪:从入门到专业的三重境界
  • 如何在群晖虚拟机快速部署线上web网站并实现公网访问
  • 向他人分享我的音频
  • - BigBosscyb - 博客园
  • 整体二分
  • 闲来无事
  • - daydreamer_zcxnb - 博客园
  • - Redamancy_Lydic - 博客园
  • - darling331 - 博客园
  • - kintsgi - 博客园
  • TIM外部中断
  • LPC总线设计及其仿真验证
  • Fluent许可证类型
  • 多值依赖
  • Windows 验证耳机输入是否正常
  • ABC典题总结
  • springboot项目解决报错:spring boot application in default package
  • LaTeX中为何推荐substack而不使用\atop?
  • 手机网页版浏览器seo案例分析及解析
  • 知名品牌vi设计宁波优化推广找哪家
  • 做国际贸易的网站沧州网站推广优化
  • 网站框架都有什么用重庆网站快速排名提升
  • 凡科自助建站靠谱吗网站安全检测在线
  • 哪些国家网站无须备案企业所得税优惠政策
  • 泰安房产网信息网官网seo服务 收费
  • ps怎样做网站详情页建立免费个人网站
  • 风中有朵雨做的云网站观看网站如何提交百度收录