《冒险公社》
冒险公社
https://ac.nowcoder.com/acm/contest/23106/K
**这题感觉挺简单的,但是没什么人写.
思路:我们钦定前两个位置是哪两种颜色的岛,然后dp去统计这种情况下的最多绿岛数量。
dp[i][j][k] - 表示位置i的颜色为k,i - 1的颜色为j.
转移的时候看一下冲不冲突就可以了。**
using namespace std;
typedef long long LL;
typedef pair<double,int> pii;
const int N = 1e5 + 5;
const int M = 1e7 + 5;
#define rep(at,am,as) for(int at = am;at <= as;++at)
const LL Mod = 10000;
#define INF 1e9
#define dbg(ax) cout << "now this num is " << ax << endl;
inline long long ADD(long long x,long long y) {
if(x + y < 0) return ((x + y) % Mod + Mod) % Mod;
return (x + y) % Mod;
}
inline long long MUL(long long x,long long y) {
if(x * y < 0) return ((x * y) % Mod + Mod) % Mod;
return x * y % Mod;
}
inline long long DEC(long long x,long long y) {
if(x - y < 0) return (x - y + Mod) % Mod;
return (x - y) % Mod;
}
int n;
string s;
//1 - red,2 - green,3 - black
int dp[N][4][4];//i的颜色为k,i - 1颜色为j.
int check(int x,int y) {
memset(dp,-1,sizeof(dp));
dp[2][x][y] = (x == 2) + (y == 2);
int mx = -1;
rep(i,1,n) {
rep(j,1,3) {
rep(k,1,3) {
if(dp[i - 1][j][k] == -1) continue;
rep(m,1,3) {
int sum1 = (j == 2) + (k == 2) + (m == 2),sum2 = (j == 1) + (k == 1) + (m == 1);
if(s[i - 1] == 'G') {
if(sum1 <= sum2) dp[i][k][m] = max(dp[i][k][m],-1);
else dp[i][k][m] = max(dp[i][k][m],dp[i - 1][j][k] + (m == 2));
}
if(s[i - 1] == 'R') {
if(sum2 <= sum1) dp[i][k][m] = max(dp[i][k][m],-1);
else dp[i][k][m] = max(dp[i][k][m],dp[i - 1][j][k] + (m == 2));
}
if(s[i - 1] == 'B') {
if(sum1 != sum2) dp[i][k][m] = max(dp[i][k][m],-1);
else dp[i][k][m] = max(dp[i][k][m],dp[i - 1][j][k] + (m == 2));
}
if(i == n) mx = max(mx,dp[i][k][m]);
}
}
}
}
return mx;
}
void solve() {
cin >> n >> s;
int ans = -1;
rep(i,1,3) {
rep(j,1,3) {
ans = max(ans,check(i,j));
}
}
printf("%d\n",ans);
}
int main() {
// int _;
// for(scanf("%d",&_);_;_--) {
solve();
//}
// system("pause");
return 0;
}