题意:给你一串01,只有相邻两位可以互换。一串把上面那个串划分为m块每块有pi的数字,求满足条件的最小步数。
思路:显然,如果第一块是0、那么第二块是1、第三块是0......即两块是不同的,所以每隔一块就是相同数字的块。那么我们就可以假定第一块是0的时候,把那些应该是1的块里的0全部移到0块里的1的最小步数之和,就是当前总最小步数;还要假定第一块是1的时候。取最小值即可。
#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include<vector>
#include<cmath>
#include<map>
#include<algorithm>
using namespace std;
int n,m;
int a[25],p[25];
int t0,t1;
int ans(int t){
int tot = 0;
int tmp[25],cnt = 0;
for(int i = 0;i < m;i += 2){
if(i+1 == m) break;
for(int j = p[i]+1;j <= p[i+1];j++){
if(a[j] == t){
tmp[cnt++] = j;
}
}
}
int last = -1,tt = 0;
for(int i = 0;i < m;i += 2){
if(i > 0) last = p[i-1];
for(int j = last+1;j <= p[i];j++){
if(a[j] != t){
tot += abs(tmp[tt++]-j);
}
}
}
return tot;
}
int main(){
while(~scanf("%d%d", &n, &m)){
t0 = 0,t1 = 0;
for(int i = 0;i < n;i++){
scanf("%d", a+i);
if(a[i]) t1 ++;
else t0 ++;
}
int cnt[3] = {0,0,0},f = 1;
for(int i = 0;i < m;i++){
scanf("%d", p+i);
cnt[1+f] += p[i];
f *= -1;
}
p[0] --; //因为我们的p数组是从0开始的,所以一定要减一
for(int i = 1;i < m;i++) p[i] += p[i-1];
if(cnt[0] != cnt[2]){
if(cnt[2] == t0) printf("%d\n", ans(0));
else printf("%d\n", ans(1));
}
else printf("%d\n", min(ans(0),ans(1)));
}
return 0;
}