2. D - Between Two Binary Strings (atcoder.jp)
D - between two binary strings
主要思考那个距离怎么解决,即怎么找出满足题意的介于s与t距离之间的串。
题目的每个条件都不是没有用的,有时还需观察样例。
对于两个串s,t属于集合(p,q)它们的0,1个数是相同的,考虑每个1所在位置。设s串中第i个1的位置是d1[i],t串中第i个1的位置是d2[i],对于s和t串,它们两个之间的距离就是 ,满足题意的同类型的串设为k,它每个1的位置设为d3[i],满足min(d1[i],d2[i]) <= d3[i] <= max(d1[i],d2[i])
接下来我们开始思考:要求最大的价值,我们应该怎样决策?我们肯定希望相同的元素能够凑在一起最好。也就是对于可供我们选择的串,我们希望相邻的1或0能够凑在一起。对k串的第i个1的,假设前面的1都已经选好位置,我们能选择的1的位置实际是在一个区间内的。
由于希望相同的凑在一起,我们思考1可不可以放在最前面。
如果此时1的最靠前的位置能够与前一个1靠在一起,能够证明此时放在最前面是最优的。证明:设当前1能放的区间是 l 到 r (闭区间),若将1放在 l+1 到 r 的区间内,当把1放到 l 的位置上时,可以发现 总价值会增加2(1与1贴贴,0与0贴贴),可知放在 l 的位置上最优。
如果此时的1的最靠前的位置不能与前一个1靠在一起,能够证明此时放在最后一定是最优的。设当前1能放的区间是 l 到 r (闭区间),若将1放在 l 到 r-1 的区间内,当把1放到 r 的位置上时,若后面的1能够与当前的1靠在一起,此时肯定最优;若后面的1不能与当前的1靠在一起,此时无论我们手中的1放在哪里,都一样。
虽然主体过程已经思考完毕,但是还有细节需要注意:由于我们的归纳假设是建立在前面1已经放好的前提下,因此在考虑放置最前面一个1时,不能按照我们前面的放法。此时只需枚举放在最前面和最后面即可:因为当不在最前面和最后面时,我们移动1得到的结果都一样。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 3e5 + 10;
int n,m,d1[N],d2[N];
string s,t;
int solve(int st){
//cout << n << "!" << endl;
int ans=0,last=st;
ans+=max(st-1,0);
for(int i=2;i<=n;i++){
//cout << last << endl;
int maxpos=max(d1[i],d2[i]),minpos=min(d1[i],d2[i]);
if(minpos<=last+1){
ans++;
last++;
}
else{
ans+=max(maxpos-last-2,0);
last=maxpos;
}
//cout << ans << "!" << endl;
}
ans+=max(n+m-1-last-1,0);
// cout << ":" << last;
// cout << ans << "!" << endl;
return ans;
}
int main(){
cin >> m >> n;
cin >> s >> t;
int h1=0,h2=0;
for(int i=0;i<s.size();i++){
if(s[i]=='1') d1[++h1]=i;
if(t[i]=='1') d2[++h2]=i;
}
int ans=solve(d1[1]);
ans=max(ans,solve(d2[1]));
cout << ans;
return 0;
}
但是WA了一个点😥
我不会,长大后再学习~~~