DPする。
dp [ i ] [ j ] = i から j までの間で作れるパターン数
意外と難しかった。
vector<int> C;
int N;
const int M = 50 + 1;
lli memo[M][M];
const lli mod = 100000007;
// [... a, b, ...]
bool next(int a, int b)
{
return (a + 1) % N == b;
}
lli rec(int i, int j)
{
if (next(i, j)) return 1;
lli &ret = memo[i][j];
if (ret != -1) return ret;
lli sum = rec(i + 1, j);
for (int k = i + 2; k < j; ++k) {
if (C[i] != C[k]) {
sum += rec(i, k) * rec(k, j) / 2LL;
sum %= 2LL * mod;
}
}
if (C[i] != C[j] && !next(i, j) && !next(j, i)) {
sum *= 2LL;
sum %= 2LL * mod;
}
return ret = sum;
}
class PolygonColors {
public:
int getWays(int N_, vector <int> C_)
{
N = N_;
C = C_;
for (int i = 0; i < (int)N; ++i) {
int j = (i + 1) % C.size();
if (C[i] == C[j]) return 0;
}
fill(&memo[0][0], &memo[M - 1][M], -1);
return rec(0, N - 1) % mod;
}
};