题目:Equalize
题意:
给出两个长度相等的
01
01
串,求把其中一种变成另一种的最下代价。
操作
1
1
:交换两个位置在的数,代价是
|i−j|
|
i
−
j
|
。
操作
2
2
:把一个数异或,代价为
1
1
。
思路:
首先可以知道,使用操作时,只能交换相邻两元素。因为如果交换的两元素距离大于
1
1
,那么使用操作一定更优。
然后令
f[i]
f
[
i
]
表示前
i
i
个数的最小代价。
当时,
f[i]=f[i−1]
f
[
i
]
=
f
[
i
−
1
]
。
当
a[i]!=b[i]
a
[
i
]
!
=
b
[
i
]
时,若
(a[i−1]==b[i] and a[i]==b[i−1] and !g[i−1])==0
(
a
[
i
−
1
]
==
b
[
i
]
a
n
d
a
[
i
]
==
b
[
i
−
1
]
a
n
d
!
g
[
i
−
1
]
)
==
0
,
f[i]=f[i−1]+1
f
[
i
]
=
f
[
i
−
1
]
+
1
。
其中g代表是否在i处做过操作
1
1
<script type="math/tex" id="MathJax-Element-1931">1</script>。
代码:
#include<bits/stdc++.h>
using namespace std;
#define maxn 1000000
#define inf (1<<30)
int n;
void read(int& x) {
char y;
while(~scanf("%c",&y)&&(y<'0'||y>'1'));
x=y-'0';
}
int a[maxn+5],b[maxn+5];
int f[maxn+5],g[maxn+5];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++) read(a[i]);
for(int i=1;i<=n;i++) read(b[i]);
for(int i=1;i<=n;i++) {
f[i]=f[i-1];
if(a[i]!=b[i]) {
if(a[i-1]==b[i]&&a[i]==b[i-1]&&!g[i-1]) g[i]=true;
else f[i]++;
}
}
printf("%d",f[n]);
return 0;
}