ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2022-06-22 20:03:01  阅读:139  来源: 互联网

标签:10 硬币 ll leq 2019 ans JOI P6117 include


正题

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


题目大意

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

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

\(1\leq n\leq 10^5,-10^9\leq X_i,Y_i\leq 10^9\)


解题思路

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

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

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

时间复杂度:\(O(n)\)


code

#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;
}

标签:10,硬币,ll,leq,2019,ans,JOI,P6117,include
来源: https://www.cnblogs.com/QuantAsk/p/16402090.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有