VP没来得及做完,顺着思路做很快就写好了
f[i][j][k][l]
表示前i位数字红色取j位,红色组成数字mod A为k,蓝色数字mod B为l的方案是否成立,按照题意无脑转移
然后最后获得每一步的决策:首先找到满足
∣
a
−
b
∣
|a-b|
∣a−b∣最小的末尾决策,然后倒着dfs搜出答案即可
当然官方的答案折半搜索也可以,但是没我的快
// #define int LL
const int N = 50,M=N*2,mod=1e9+7;
int n,m,cnt,A,B;
string p;
int f[N][N][N][N];
int MMod(int x,int mod){
return (x%mod+mod)%mod;
}
int MMod(int x,int y,int mod){
return Mod(x-y,mod);
}
void print(int i,int j,int k,int l){
cout<<"f["<<i<<"]["<<j<<"]["<<k<<"]["<<l<<"]="<<f[i][j][k][l]<<endl;
}
vector<char> res;
void dfs(int num,int red,int modred,int modblue){
// print(num,red,modred,modblue);
if(num==0) return ;
int nw=p[num]-'0';
if(red>0)
for(int i=0;i<A;++i)
if((i*10+nw)%A==modred)
if(f[num-1][red-1][i][modblue]){
res.push_back('R');
dfs(num-1,red-1,i,modblue);
return ;
}
if(red!=num)
for(int i=0;i<B;++i)
if((i*10+nw)%B==modblue)
if(f[num-1][red][modred][i]){
res.push_back('B');
dfs(num-1,red,modred,i);
return ;
}
}
void solve(){
res.clear();
cin>>n>>A>>B;
cin >> p;
p="."+p;
//f[i][j][k][l] 前i个数,红色有j个余数为k,黑色余数为l的最大
f[0][0][0][0]=1;
rep(i,0,n-1){
int nw=p[i+1]-'0';
rep(j,0,i)
rep(k,0,A-1)
rep(l,0,B-1){
f[i+1][j+1][(k*10+nw)%A][l]+=f[i][j][k][l];
f[i+1][j][k][(l*10+nw)%B]+=f[i][j][k][l];
}
}
bool ok=false;
int pos=0;//debug(pos);
for(int i=1;i<=n-1;++i) {
if(f[n][i][0][0]) {
ok=true;
if(abs(pos-(n-pos))>abs(i-(n-i))) pos=i;
}
}
if(ok){
dfs(n,pos,0,0);
reverse(res.begin(),res.end());
for(auto u:res) printf("%c",u);
puts("");
}
else print(-1);
rep(i,1,n) rep(j,0,n) rep(k,0,A-1) rep(l,0,B-1) {
f[i][j][k][l]=0;
}
}
//=================================
signed main(){
int _=read();
while(_--) solve();
return 0;
}