将序列分成两半,各n各字符。对于前一半,枚举每个字符属于T1还是T2,共2^n种情况。在一个方案中,T1的子序列为A,T2的子序列为B,我们假定A的长度不大于B的长度。显然,A是B的前缀才符合要求。令C=B-A,即B去掉A前缀后剩余的部分。同理,处理后一半得到一个C‘,就是去掉相同后缀后剩余的部分。当C=C'就是一个方案使得T1=T2。
主要有两点十分巧妙:1.枚举过程可以控制t1长度<=t2,这样能减少一半的枚举,但是会漏掉一些情况,比如第一个字符总是放在t2,实际也能放在t1,于是在len1==len2时另外交换两个串进行枚举。
2.如何快速匹配呢?我们记录的是两部分的权值之差,应该是取两部分w1-w2之和绝对值最小,可以变换为第一部分w1-w2和第二部分w2-w1之差绝对值最小,这样我们就记录第一部分的w1-w2,第二部分的w2-w1,现根据C排序,在根据权值之差排序,于是相邻的C和C'之差最小,可以O(n)解决。另外由于内存不够,把字符串C转化成数字,并记录长度,按长度排序再按C大小排序再按权值排序。
#include<iostream>
#include<string>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<iomanip>
#include<map>
#include<algorithm>
#include<queue>
#include<set>
#define inf 1000000000
#define pi acos(-1.0)
#define eps 1e-8
#define seed 131
using namespace std;
typedef pair<int,int> pii;
typedef unsigned long long ull;
typedef long long ll;
const int maxn=100005;
char s[50];
int d[50];
int n;
struct Node
{
bool flag;
int len;
ll p;
int w;
bool operator<(const Node& u)const
{
if(len==u.len)
{
if(p==u.p)
return w>u.w;
return p<u.p;
}
return len<u.len;
}
};
Node vec[2500000];
int num;
char t1[50],t2[50];
int w1,w2;
int len1,len2;
void dfs1(int u)
{
if(u==n+1)
{
vec[num].flag=1;
vec[num].len=len2-len1;
vec[num].w=w1-w2;
ll m=0;
for(int i=len1;i<len2;i++)
{
if(t2[i]=='a')
m=m*10+1;
else
m=m*10;
}
vec[num++].p=m;
if(len1==len2)
{
vec[num].flag=1;
vec[num].len=len2-len1;
vec[num].w=w2-w1;
vec[num++].p=m;
}
return;
}
if(len1<len2&&s[u]==t2[len1])
{
t1[len1++]=s[u];
w1+=d[u];
dfs1(u+1);
len1--;
w1-=d[u];
}
t2[len2++]=s[u];
w2+=d[u];
dfs1(u+1);
len2--;
w2-=d[u];
if(len1==len2)
{
t2[len2++]=s[u];
swap(w1,w2);
w2+=d[u];
dfs1(u+1);
len2--;
w2-=d[u];
swap(w1,w2);
}
}
void dfs2(int u)
{
if(u==2*n+1)
{
vec[num].flag=0;
vec[num].len=len1-len2;
ll m=0;
for(int i=len1-1;i>=len2;i--)
{
if(t1[i]=='a')
m=m*10+1;
else
m=m*10;
}
vec[num].p=m;
vec[num++].w=w2-w1;
if(len1==len2)
{
vec[num].flag=0;
vec[num].len=len1-len2;
vec[num].p=m;
vec[num++].w=w1-w2;
}
return;
}
t1[len1++]=s[u];
w1+=d[u];
dfs2(u+1);
len1--;
w1-=d[u];
if(len1==len2)
{
t1[len1++]=s[u];
swap(w1,w2);
w1+=d[u];
dfs2(u+1);
len1--;
w1-=d[u];
swap(w1,w2);
}
if(len2<len1&&s[u]==t1[len2])
{
t2[len2++]=s[u];
w2+=d[u];
dfs2(u+1);
len2--;
w2-=d[u];
}
}
int main()
{
int a,b;
while(~scanf("%d",&n)&&n)
{
a=0;b=0;
scanf("%s",s+1);
for(int i=1;i<=2*n;i++)
{
if(s[i]=='a')
a++;
if(s[i]=='b')
b++;
}
for(int i=1;i<=n*2;i++)
scanf("%d",&d[i]);
if((a&1)||(b&1))
{
printf("-1\n");
continue;
}
for(int i=n+1,j=2*n;i<j;i++,j--)
{
swap(s[i],s[j]);
swap(d[i],d[j]);
}
if(a%2!=0||b%2!=0)
{
printf("-1\n");
continue;
}
w1=w2=0;
num=0;
len1=len2=0;
dfs1(1);
w1=w2=0;
len1=len2=0;
dfs2(n+1);
sort(vec,vec+num);
int ans=inf;
int p=-1,q=-1;
for(int i=0;i<num;i++)
{
if(vec[i].flag==1)
{
p=i;
if(i-1>=0&&(vec[i].p!=vec[i-1].p||vec[i].len!=vec[i-1].len))
q=-1;
}
if(vec[i].flag==0)
{
q=i;
if(i-1>=0&&(vec[i].p!=vec[i-1].p||vec[i].len!=vec[i-1].len))
p=-1;
}
if(p==-1||q==-1)
continue;
ans=min(ans,abs(vec[p].w-vec[q].w));
}
if(ans==inf)
printf("-1\n");
else
printf("%d\n",ans);
}
return 0;
}