ICode9

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

ARC132D-Between Two Binary Strings【贪心】

2021-12-27 11:06:51  阅读:155  来源: 互联网

标签:Binary ARC132D int Two 字符串 边界 考虑 include dis


正题

题目链接:https://atcoder.jp/contests/arc132/tasks/arc132_d


题目大意

给出两个恰好有\(n\)个\(1\)和\(m\)个\(0\)的字符串\(s,t\),定义两个字符串距离为通过交换两个相邻的字符把一个变成另一个的最小步数。

对于字符串\(k\)如果\(dis(s,k)+dis(k,t)=dis(s,t)\)那么\(k\)在\(s,t\)之间。

定义一个字符串的权值为相邻的相同字符对数。

求所有在\(s,t\)之间的字符串中权值最大是多少。

\(1\leq n+m\leq 3\times 10^5\)


解题思路

先考虑在\(s,t\)之间的字符串有什么性质,显然的我们对于求\(dis(s,t)\)的时候最优的策略肯定是把\(s\)的第\(i\)个\(1\)移动到\(t\)的第\(i\)个\(1\)处。

也就是对于两个串中第\(i\)个\(1\)的位置记为\(x,y\),那么就是一个一要从\(x\rightarrow y\),也就是在\(s\sim t\)之间的字符串第\(i\)个一肯定在\(x\sim y\)这个范围。

这样我们处理出每个\(1\)的合法区间\(l_i,r_i\),显然的\(l_i\)和\(r_i\)必定递增,因为交换两个\(1\)的顺序必定不划算。所以可以考虑贪心。

不考虑边界的问题,那么我们显然要让\(1\)的连续段尽量少,那么从小到大考虑\(l,r\)如果能和上一个放一起就放一起,不然就放在\(r\)的位置最赚。

然后考虑边界,右边界可以直接判断因为我们肯定是尽量往右放的。左边界的话我们如果\(l_1=1\)我们就分两种情况考虑,也就是第一个放在左边界和第一个放在\(r_1\)两种情况取个最大值。

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


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#define lowbit(x) (x&-x)
using namespace std;
const int N=6e5+10;
int A,B,m,n,t[N],l[N],r[N],ans,prt;
char a[N],b[N];
//void Change(int x,int val){
//	while(x<=m){
//		t[x]+=val;
//		x+=lowbit(x);
//	}
//	return;
//}
//int Ask(int x){
//	int ans=0;
//	while(x){
//		ans+=t[x];
//		x-=lowbit(x);
//	}
//	return ans;
//}
int main()
{
	scanf("%d%d",&A,&B);m=A+B;
	scanf("%s",a+1);
	scanf("%s",b+1);
	for(int i=1;i<=m;i++)
		if(a[i]=='1')l[++n]=i;
	n=0;
	for(int i=1;i<=m;i++)
		if(b[i]=='1')r[++n]=i;
	for(int i=1;i<=n;i++){
		if(l[i]>r[i])swap(l[i],r[i]);
	}
	int last=-1;
	for(int i=1;i<=n;i++){
		if(l[i]<=last+1)last++;
		else ans++,last=r[i];
	}
	ans=ans*2;
	if(last!=m)ans++;
	prt=m-ans;
	if(l[1]==1){
		last=1;ans=1;
		for(int i=2;i<=n;i++){
			if(l[i]<=last+1)last++;
			else ans+=2,last=r[i];
		}
		if(last!=m)ans++;
		ans=m-ans;
		prt=max(prt,ans);
	}
	printf("%d\n",prt);
	return 0;
}

标签:Binary,ARC132D,int,Two,字符串,边界,考虑,include,dis
来源: https://www.cnblogs.com/QuantAsk/p/15735415.html

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

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

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

ICode9版权所有