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

P1081 [NOIP 2012 提高组] 开车旅行

  • 预处理出小A和小B在每个城市下次到达的城市,即距离每个点的最近点和次近点

    • 本题中如果当前城市到两个城市的距离相同,则认为离海拔低的那个城市更近

      • \(sort\) 将海拔 \(h\) 排序,并用 \(b\) 数组记录出排序后每个城市的位置,b[原编号]=排序后的位置
    • 编号较小的城市在编号较大的城市的西边,且计划一直向东行驶

      • 即一直向初始编号大的城市行驶,可以从\(1\rightarrow n\)遍历初始编号,走过一个城市删一个,这样可以保证在考虑范围内的城市全部都是初始编号比当前城市大的

      • 要维护与当前城市距离最近的两座城市,以及支持删除操作,用双向链表维护

      • \(eg:\)

        \(h\)数组:\(\enclose{circle}{1}\) \(\enclose{circle}{2}\) \(\enclose{circle}{3}\) \(\enclose{circle}{4}\)

        \(\qquad\quad\,\large5\) \(\,\,\,\large1\) \(\,\,\large7\) \(\,\,\,\large4\)

        \(b\)数组:\(b[2]=1 \quad b[4]=2 \quad b[1]=3 \quad b[3]=4\)

        \(\enclose{circle}{2}\) \(\enclose{circle}{4}\) \(\enclose{circle}{1}\) \(\enclose{circle}{3}\)

        \(\,\,\large1\) \(\,\,\large4\) \(\,\,\large5\) \(\,\,\large7\)

        \[\enclose{circle}{1} \Longleftrightarrow \enclose{circle}{2} \Longleftrightarrow\enclose{circle}{3} \Longleftrightarrow \enclose{circle}{4} \]

        \(i=1\)时,\(u=pre[b[i]]=2,\ v=nxt[b[i]]=4\)

        \[\enclose{circle}{1} \Longleftrightarrow \enclose{circle}{2} \Longleftrightarrow \enclose{circle}{4} \]

        \(i=2\)时,\(u=pre[b[i]]=\emptyset,\ v=nxt[b[i]]=2\)

        \[\ \enclose{circle}{2} \Longleftrightarrow \enclose{circle}{4} \]

        \(i=3\)时,\(u=pre[b[i]]=2,\ v=nxt[b[i]]=\emptyset\)

        \[\enclose{circle}{2} \]

      • for(int i=1;i<=n;i++){cin>>a[i].h;a[i].id=i;nxt[i]=i+1;pre[i]=i-1;}nxt[0]=nxt[n]=0;sort(a+1,a+1+n,cmp);for(int i=1;i<=n;i++)b[a[i].id]=i;//A数组,B数组:下次到达城市的序号,AW,BW:行驶的路程for(int i=1;i<=n;i++){int u=pre[b[i]],v=nxt[b[i]];if(!u&&!v) continue;if(v&&(!u||abs(a[u].h-a[b[i]].h)>abs(a[v].h-a[b[i]].h))){B[i]=a[v].id;BW[i]=abs(a[v].h-a[b[i]].h);}else if(u&&(!v||abs(a[v].h-a[b[i]].h)>abs(a[u].h-a[b[i]].h))){B[i]=a[u].id;BW[i]=abs(a[u].h-a[b[i]].h);}else if(u&&v){if(abs(a[v].h-a[b[i]].h)<abs(a[u].h-a[b[i]].h)){B[i]=a[v].id;BW[i]=abs(a[v].h-a[b[i]].h);}else{B[i]=a[u].id;BW[i]=abs(a[u].h-a[b[i]].h);}}if(u) nxt[u]=v;if(v) pre[v]=u;}for(int i=1;i<=n;i++){nxt[i]=i+1;pre[i]=i-1;}pre[0]=nxt[n]=nxt[0]=0;for(int i=1;i<=n;i++){int u=pre[b[i]],v=nxt[b[i]];if(!u&&!v) continue;if((!u&&nxt[v])||(u&&nxt[v]&&abs(a[u].h-a[b[i]].h)>abs(a[b[i]].h-a[nxt[v]].h))){A[i]=a[nxt[v]].id;AW[i]=abs(a[b[i]].h-a[nxt[v]].h);}else if((!v&&pre[u])||(v&&pre[u]&&abs(a[v].h-a[b[i]].h)>=abs(a[pre[u]].h-a[b[i]].h))){A[i]=a[pre[u]].id;AW[i]=abs(a[pre[u]].h-a[b[i]].h);}else if(u&&v){//距离相等时选前驱对应题目中"距离相同则选海拔较低"的规则(前驱海拔更低)if(abs(a[v].h-a[b[i]].h)<abs(a[u].h-a[b[i]].h)){A[i]=a[u].id;AW[i]=abs(a[u].h-a[b[i]].h);}else{A[i]=a[v].id;AW[i]=abs(a[v].h-a[b[i]].h);}}if(u) nxt[u]=v;if(v) pre[v]=u;}
        

        注意判定当前元素的前驱和后继不存在的情况

  • 倍增优化移动过程

    • \(s[i][j]\) 表示从\(i\)号节点小\(A\)和小\(B\)各走\(2^j\)步到达的节点

      \(SW[i][j]\) 表示从\(i\)号节点小\(A\)和小\(B\)各走\(2^j\)步的权值

      \(SA[i][j]\) 表示从\(i\)号节点小\(A\)\(2^j\)步的权值

      \(SB[i][j]\) 表示从\(i\)号节点小\(B\)\(2^j\)步的权值

    • for(int i=1;i<=n;i++){if(A[i]&&B[A[i]]){s[i][0]=B[A[i]];SW[i][0]=min(INF,AW[i]+BW[A[i]]);SB[i][0]=min(INF,BW[A[i]]);SA[i][0]=min(INF,AW[i]);}}for(int j=1;j<20;j++){for(int i=1;i<=n;i++){if(s[i][j-1]&&s[s[i][j-1]][j-1]){s[i][j]=s[s[i][j-1]][j-1];SW[i][j]=min(INF,SW[i][j-1]+SW[s[i][j-1]][j-1]);SB[i][j]=min(INF,SB[i][j-1]+SB[s[i][j-1]][j-1]);SA[i][j]=min(INF,SA[i][j-1]+SA[s[i][j-1]][j-1]);}}}
      
  • \(question\)

    • \(question1:\) 枚举出发城市 \(s\),从大往小尝试行驶的组数以二为底数的幂指数,满足条件就行驶,累加总路程与小\(A\)和小\(B\)行驶的路程,到达极限后,再尝试一下小\(A\)能不能再走,最后用交叉相乘比较大小

      • \(ans1\)记录小\(A\)的路程,\(ans2\)记录小\(B\)的路程,初始化\(ans1=10^9+5,\, ans2=0\) (\(x_i\leq 10^9\)所以\(ans1\)的初始值必须比\(10^9\)大,设为极值)
    • \(question2:\) 从大往小尝试行驶的组数以二为底数的幂指数,满足条件就行驶,累加小\(A\)和小\(B\)行驶的路程,到达极限后,再尝试一下小\(A\)能不能再走

    • 	cin>>x;int ans1=INF+1,ans2=0,t=0;//t记录编号 for(int i=1;i<=n;i++){int sA=0,sB=0,S=0;int u=i;for(int j=19;j>=0;j--){if(s[u][j]){if((ll)S+SW[u][j]<=x){S+=SW[u][j];sA+=SA[u][j];sB+=SB[u][j];u=s[u][j];}}}if(A[u]&&S+AW[u]<=x) sA+=AW[u];if((ll)ans1*sB>(ll)sA*ans2){ans1=sA;ans2=sB;t=i;}}cout<<t<<'\n';cin>>m;while(m--){cin>>st>>x;int S=0,sA=0,sB=0;for(int j=19;j>=0;j--){if(s[st][j]){if((ll)S+SW[st][j]<=x){S+=SW[st][j];sA+=SA[st][j];sB+=SB[st][j];st=s[st][j];}}}if(A[st]&&S+AW[st]<=x) sA+=AW[st];cout<<sA<<" "<<sB<<'\n';} 
      
http://www.zskr.cn/news/1482082.html

相关文章:

  • 如何用Python在3分钟内构建企业级抖音批量下载解决方案
  • 成都旧房翻新价格多少?2026年报价明细+避坑指南+公司对比 - 优家闲谈
  • 别再瞎找AI写论文工具!6款全学科神器,一键极速搞定毕业论文 - 麟书学长
  • 020、配置调试与故障诊断:claude config 诊断命令与 10 个常见错误的修复方案
  • Pearcleaner终极指南:免费开源macOS深度清理工具,彻底告别应用残留
  • C51单片机XBYTE宏详解:外部总线访问与内存映射I/O实战
  • 抖音批量下载工具完全指南:5分钟掌握无水印视频下载技巧
  • 嵌入式触摸屏数字键盘实现:图片映射与区域检测方案详解
  • 抖音批量下载终极指南:5分钟免费获取无水印视频素材
  • 2026回本实测解密:68%商家AI直播闲置亏损!
  • 压敏电阻选型与应用指南:从原理到电路保护设计
  • Chrome浏览器密码输入行为捕获工具:专为授权安全测试设计的轻量级扩展
  • 营业执照OCR识别接口接入实践:文档解析、请求校验与工程化落地指南
  • 杭州阿里总部周边5家广式鸡煲店实测排行 - 奔跑123
  • 手把手写你的第一个 Skill:5 分钟搞定
  • Packmol分子动力学模拟初始构型构建完全指南:从入门到精通
  • D类功放原理与实战:从PWM调制到PCB布局全解析
  • 3分钟掌握Whisky:在Mac上运行Windows程序的终极方案
  • 51单片机入门:从环境搭建到点亮LED的嵌入式开发实战指南
  • 千元迷你主机选购指南:英特尔N150芯片解析与三款热门机型横评
  • 终极指南:用Python快速获取同花顺问财数据的完整教程
  • Fillinger智能填充插件:Illustrator设计效率提升18倍的终极指南
  • Kubernetes HPA 自动扩缩容实战:从基础 CPU 指标到自定义指标的全链路调优
  • 音乐格式转换终极指南:Unlock Music高效解锁加密音频文件解决方案
  • 如何在Windows上轻松管理MIFARE Classic智能卡?MifareOneTool的完整解决方案
  • 基于 Simulink 的轨道车辆牵引电机直接转矩控制(DTC)及其磁链观测器仿真实战教程
  • 硬件电路设计中的电容精度计算与最坏情况分析实践
  • Nios II uClinux系统构建实战:从环境搭建到内核启动
  • VC6平台下用WaveIn/WaveOut实现的实时录音+播放+保存工程(含环形缓冲与滤波)
  • 仅限技术博主内部流通:CSDN AI停用后权重留存率TOP20%作者共用的3个反衰减黑盒配置(含Nginx+Canonical实操代码)