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