/*
终态分析:和生活中一样一定是有两种齿轮同一个方向,另一个齿轮为连接这两个齿轮的辅助齿轮
于是我们可以分三中情况枚举
对于辅助的齿轮我们可以忽略因为它不会出现矛盾的情况
对于剩下的齿轮(构成了一个二分图)我们要构造一个集合使他们互不相连
即求二分图的最大独立集(最大独立集=总点数-最大匹配)
我们需要删除的齿轮即为最大独立集外剩下齿轮的一半
*/
#include<bits/stdc++.h>
using namespace std;
const int M=55;
char c[M],K[M][M];
int to[M],n;
bool vis[M];
vector<int>A[3];
vector<int>G[M];
bool dfs(int x){
for(int i=0;i<G[x].size();i++){
int y=G[x][i];
if(vis[y])continue;
vis[y]=1;
if(!~to[y]||dfs(to[y])){
to[y]=x;
return 1;
}
}return 0;
}
int solve(int x,int y){
for(int i=0;i<n;i++)G[i].clear();
for(int i=0;i<A[x].size();i++)
for(int j=0;j<A[y].size();j++){
int a=A[x][i],b=A[y][j];
if(K[a][b]=='Y'){
G[a].push_back(b);
G[b].push_back(a);
}
}
memset(to,-1,sizeof(to));
int cnt=0;
for(int i=0;i<n;i++){
memset(vis,0,sizeof(vis));
cnt+=dfs(i);
}return cnt/2;
}
int main(){
scanf("%d",&n);
scanf("%s",c);
for(int i=0;i<n;i++){
if(c[i]=='R')A[0].push_back(i);
else if(c[i]=='G')A[1].push_back(i);
else A[2].push_back(i);
}
for(int i=0;i<n;i++)scanf("%s",K[i]);
int R=solve(1,0);
int G=solve(2,0);
int B=solve(1,2);
printf("%d",min(G,min(B,R)));
}
SRM589 Div1 450
最新推荐文章于 2017-05-04 20:13:03 发布