• ARC132DBetween Two Binary Strings【贪心】


    正题

    题目链接: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;
    }
    
  • 相关阅读:
    HTML5的audio在手机网页上无法自动加载/播放音乐,能否实现该功能?
    cef3加载flash闪烁问题非easyhook的另外一种解决方法
    CEF加载FLASH插件时弹出CMD命令行窗口的问题
    【解决】 无法打开包括文件:“windows.h”: No such file or directory
    C# 把字符串类型日期转换为日期类型
    request:fail 小程序要求的 TLS 版本必须大于等于 1.2
    提高SQL查询效率
    jQuery设置下拉框select 默认选中第一个option
    解决浏览器Adobe Flash Player不是最新版本问题
    怎样在WIN7系统下安装IIS
  • 原文地址:https://www.cnblogs.com/QuantAsk/p/15735415.html
Copyright © 2020-2023  润新知