洛谷-题解 P2672 【推销员】
独门思路!链表加优先队列!
这题一望,贪心是跑不掉了,但是我贪心并不好,所以想到了一个复杂一些但思路更保稳的做法
思路:
1 因为是离线操作,所以我们可以倒着求,先求x=n的情况,因为那样直接就知道了
2 用优先队列维护每个住户对疲劳度的贡献,维护最小的,因为x=i的疲劳度减去此时减去对疲劳度贡献最小的用户当然为x=i-1的疲劳度的最大值
3 需要用链表,因为当某个用户自己本身距离最远或比自己距离远且相邻的用户距离最远,那么删去这个用户,其他两个用户对疲劳度贡献分别更新(往返距离变化了)
4 一些小的细节,保证正确,因为优先队列里会有一些无用的用户
下面是可以简化和优化的代码,供参考思路
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<algorithm> 5 #include<cstring> 6 #include<queue> 7 #include<map> 8 using namespace std; 9 #define re register int 10 inline int read(){ 11 int x=0,ff=1;char c=getchar(); 12 while(c<'0'||c>'9'){if(c=='-')ff=-1;c=getchar();} 13 while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();} 14 return x*ff; 15 } 16 struct book{ 17 int x,i,b; 18 bool friend operator <(book xx,book yy){ 19 return xx.x>yy.x; 20 } 21 //重载运算 22 }; 23 priority_queue<book>dl; 24 int a[100005],c[100005],tot[100005]; 25 //a和c是距离和疲劳度,tot记录答案 26 int lb[100005],to[100005],s,tt[100005]; 27 //lb是前驱,rb是后驱(链表)tt表示此时对i用户距离修改次数,与book中的b对应 28 bool v[100005],tl[100005]; 29 //v表示次用户是否删过(其实可以省略)tl表示此点是否为最远距离 30 int main(){ 31 int n=read(),t;t=n; 32 for(int i=1;i<=n;i++){ 33 a[i]=read(); 34 } 35 for(int i=1;i<n;i++){ 36 c[i]=read();lb[i]=i-1;to[i]=i+1; 37 dl.push((book){c[i],i,0});s+=c[i]; 38 //入队,并求出x=n的疲劳度,维护链表 39 } 40 c[n]=read();lb[n]=n-1;s+=c[n]+a[n]*2; 41 dl.push((book){c[n]+(a[n]-a[n-1])*2,n,1}); 42 //初始化,与下面入队思路类似 43 tt[n]=1;tl[n]=1; 44 while(t){ 45 if(dl.empty())break; 46 tot[t]=s; 47 book y=dl.top();dl.pop(); 48 if(y.b<tt[y.i])continue; 49 //判断此用户是否为最新状态 50 if(v[y.i])continue; 51 v[y.i]=1; 52 //是否已删去 53 t--; 54 to[lb[y.i]]=to[y.i]; 55 lb[to[y.i]]=lb[y.i]; 56 //更新链表 57 s-=y.x;//更新疲劳度 58 //下面是关于前驱和后继的两种特殊情况 59 if(y.b){ 60 if(lb[y.i]==0)break;tt[lb[y.i]]++; 61 dl.push((book){c[lb[y.i]]+2*(a[lb[y.i]]-a[lb[lb[y.i]]]),lb[y.i],tt[lb[y.i]]}); 62 //特殊入队,表示此用户成为最远的,要更新删去此点的代价,注意,是往返 63 //其他入队于此类似 64 } 65 if(tl[to[y.i]]){ 66 tt[to[y.i]]++; 67 dl.push((book){c[to[y.i]]+2*(a[to[y.i]]-a[lb[y.i]]),to[y.i],tt[to[y.i]]}); 68 } 69 } 70 for(int i=1;i<=n;i++){ 71 printf("%d\n",tot[i]); 72 //输出,此程序是离线做的 73 } 74 return 0; 75 }
洛谷上第39篇题解,这样管理员都给过可见我思路有多神奇
洛谷博客求赞
转载于:https://www.cnblogs.com/ffrxy01bt/p/11099707.html
洛谷-题解 P2672 【推销员】相关推荐
- 洛谷题解——P2814 家谱
题目相关 题目链接 洛谷,https://www.luogu.com.cn/problem/P2814. MYOJ,http://47.110.135.197/problem.php?id=5344. ...
- 【洛谷题解】P2433 【深基1-2】小学数学 N 合一
目录 [深基1-2]小学数学 N 合一 题解 题目描述 输入格式 输出格式 样例 #1 样例输入 #1 样例输出 #1 题目解析 问题 1~5 问题 6~10 问题 10~14 发牢骚 完整代码 谢谢 ...
- 洛谷题解——P1621 集合
题目相关 题目链接 洛谷,https://www.luogu.com.cn/problem/P1621. MYOJ,http://47.110.135.197/problem.php?id=5342. ...
- 洛谷题解——P1873:砍树
视频讲解可以直接点击这个 B 站链接,https://www.bilibili.com/video/BV1jk4y1k7hq/. 题目相关 题目链接 洛谷,https://www.luogu.com. ...
- 洛谷题解——P1024:一元三次方程求解
视频讲解可以直接点击这个 B 站链接,https://www.bilibili.com/video/BV1qT4y13717/. 题目相关 题目链接 洛谷,https://www.luogu.com. ...
- 题解系列009 | 洛谷题解 CF488A 【Giga Tower】
原题传送门:Giga Tower 一.题意 题目(传送门)给一个绝对值不超过十位的整数,想计算至多加几后会在和数中出现数字 888. 二.分析 看到这道题,我们最容易想到的当然是暴力枚举,但是首先需要 ...
- 【洛谷题解】P2356 弹珠游戏
本人第一篇题解 今天闲着没事,随机跳题,然后看到这题,觉得运气爆棚,计蒜客L2时空复杂度的课后原题,微改. 首先,这题我们可以知道枚举处理就行,注意点: 1.千万要分清每个数组的用途,不要写错!!本蒟 ...
- 洛谷题解 P1713 【麦当劳叔叔的难题】
这是一道很好的搜索题. 既然是最大时间与最小时间的差,所以可以先用BFS求出最少时间:再用DFS求出最大时间(但注意要剪枝,不然会超时). 话不多说,进入正题. 既然可以有四个方向可以走,那么我们可以 ...
- 【洛谷题解】P5734 【深基6.例6】文字处理软件(C语言)
P5734 [深基6.例6]文字处理软件 题目描述 你需要开发一款文字处理软件.最开始时输入一个字符串(不超过 100 个字符)作为初始文档.可以认为文档开头是第 0 个字符.需要支持以下操作: 1 ...
最新文章
- JavaScript 事件冒泡简介及应用(转)
- Kobolds and Catacombs 思维,模拟,前缀,后缀(沈阳)
- win7下不能替换系统文件的解决办法
- linux系统创建windows启动盘
- Python练习:平方值格式化
- 解决js动态改变dom元素属性后页面及时渲染问题
- ueditor关闭元素
- 微信小程序手动获取自己位置wx.chooseLocation
- 安卓开发小程序之美图秀秀
- 微信人格专业测试软件,如何在微信公众号中关联《九型人格测试专业版》小程序?...
- 计算机visio流程图,系统流程图和Visio
- MATLAB学习之泰勒展开(四)
- 《中国通史》纪录片100集笔记(持更)
- 光谱预处理方法综述及分析策略选择
- 计算机公司经营范围安防监控,监控安防在个体经营范围怎么写?
- 淘宝技术发展 - 子柳撰写
- LeetCode初级算法之其他:191 位1的个数
- 平安好医生发布半年报,“关键先生”方蔚豪寻求变阵|看财报
- 转行软件测试,现状以及就业前景,你后悔了吗?
- Typora常用快捷键