P6117-[JOI 2019 Final]コイン集め【贪心】

1|0正题

题目链接:https://www.luogu.com.cn/problem/P6117


1|1题目大意

平面上有2n的硬币,要给每个硬币匹配一个x[1,n],y[1,2]的位置(不能重复)。

使得所有硬币和它们匹配位置的曼哈顿距离之和最小。

1n105,109Xi,Yi109


1|2解题思路

先把每个硬币先移进x[1,n],y[1,2]这个范围内,然后考虑贪心去把每个硬币匹配。

我们在同一个x的硬币如果上下直接能够补充缺口那么肯定优先上下补充。

不然就从左到右考虑,那么最左边的肯定往右移动多余/请求空缺,记fi,j表示位置(i,j)现在的需求情况即可。

时间复杂度:O(n)


1|3code

#include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const ll N=1e5+10; ll n,g[N][2],ans; signed main() { scanf("%lld",&n); for(ll i=1,x,y;i<=2*n;i++){ scanf("%lld%lld",&x,&y); if(y>=2)ans+=y-2,y=2; else ans+=1-y,y=1; if(x>n)ans+=x-n,x=n; else if(x<1)ans+=1-x,x=1; g[x][y-1]++; } for(ll i=1;i<=n;i++){ g[i][0]--;g[i][1]--; if(g[i][0]*g[i][1]<0){ if(g[i][0]<0){ ll p=min(-g[i][0],g[i][1]); g[i][0]+=p;g[i][1]-=p; ans+=p; } else{ ll p=min(g[i][0],-g[i][1]); g[i][0]-=p;g[i][1]+=p; ans+=p; } } ans+=abs(g[i][0])+abs(g[i][1]); g[i+1][0]+=g[i][0]; g[i+1][1]+=g[i][1]; } printf("%lld\n",ans); return 0; }

__EOF__

本文作者QuantAsk
本文链接https://www.cnblogs.com/QuantAsk/p/16402090.html
关于博主:退役OIer,GD划水选手
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   QuantAsk  阅读(44)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示