Codeforces Round #661 (Div. 3)

D. Binary String To Subsequences(队列)(贪心)

题意

你被给予了一个二进制字符串包含n个零和n个一。你的任务是分割这个字符串为最小的数量的子串,使得这些子串为'010101...'或者'101010...',输出每个字符属于的字符串编号。

分析

一开始想的是,字符个数为o(n),应该是一个线性的时间复杂度或者是o(nlogn)的时间复杂度,如果当前字符是'0',就查看是否之前存在过一个被分割的子串的结尾是'1',有的话就立马接上去,'0'的话也同理,如果接上去,那么就变成了一个新的末尾是相反字符的新子串,比如之前已经分割过一个'101',我们只能把'0'接在这个新子串的结尾,那么就变成'1010',产生了一个末尾是0的新子串的状态,原先的状态没了,暗示我们可以用队列处理,我们用pos记录第i个字符属于的字符串编号,扫描一遍每个字符,查看是否队列中存在和当前字符相反的末尾字符的子串,如果存在,那么就把当前字符的编号置为这个子串相同的编号。

代码

#include<bits/stdc++.h>
#define int long long
#define ls(k) (k)<<1
#define rs(k) (k)<<1|1
#define _0for(i, a) for(int i = 0; i < (a); ++i)
#define _1for(i, a) for(int i = 1; i <=(a); ++i)
#define lowbit(x) ((x)&(-x))
#define debug(x) \
(void)(cerr << "L" << __LINE__\
			<< " : " << #x << " = " \
			<< (x) << endl )
using namespace std;
inline int read()
{
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
int a[100],b[100];
main(void)
{
	int t=read();
	while(t--)
	{
		int n=read();
		int ma=1000000000;
		int mb=1000000000;
		_1for(i,n)
		{
			a[i]=read();
			ma=min(ma,a[i]);
		}
		_1for(i,n)
		{
			b[i]=read();
			mb=min(mb,b[i]);
		}
		int ans=0;
		for(int i=1;i<=n;i++)
		{
			int ax=a[i]-ma;
			int ay=b[i]-mb;
			ans+=max(ax,ay); 
		}
		printf("%lld\n",ans);
	}
}

posted @ 2020-08-07 15:42  王乾宇  阅读(81)  评论(1编辑  收藏  举报