4.吃蛋糕 //山东省第五届ACM省赛 C - Colorful Cupcakes
/*
题意:n块蛋糕 3种颜色A,B,C 分给一个圆桌n个人 相邻两人颜色不同
思路:五维数组 1维代表开始的颜色,2,3,4维代表三种颜色使用的次数
5维代表上一次使用的蛋糕是哪一种
*/
LL num[5][maxn][maxn][maxn][5];
int numa, numb, numc, sum; //abc三种颜色的数量
int dfs(int a, int b, int c, int t, int start)
{
if(a > numa || b > numb || c > numc) return 0;//任意一种蛋糕被吃光
if(a + b + c == sum && t == start) return 0; //全部分配完且结尾和开头相等
//不为-1 已被更新 且 不合法状态已经排除
if(num[start][a][b][c][t] != -1) return num[start][a][b][c][t];
if(a + b + c == sum && t != start) return 1; //最终状态
LL ans = 0;
if(t == 1) {
ans = (ans + dfs(a, b + 1, c, 2, start)) % mod;
ans = (ans + dfs(a, b, c + 1, 3, start)) % mod;
return num[start][a][b][c][t] = ans; //记忆化点
}
if(t == 2) {
ans = (ans + dfs(a + 1, b, c, 1, start)) % mod;
ans = (ans + dfs(a, b, c + 1, 3, start)) % mod;
return num[start][a][b][c][t] = ans;
}
if (t == 3) {
ans = (ans + dfs(a + 1, b, c, 1, start)) % mod;
ans = (ans + dfs(a, b + 1, c, 2, start)) % mod;
return num[start][a][b][c][t] = ans;
}
}
int main()
{
int Test;
char s[100];
scanf("%d", &Test);
while (Test--) {
numa = 0; numb = 0; numc = 0;
mem(num, -1);
scanf("%s", &s);
LL ans = 0;
sum = strlen(s);
for (int i = 0; i < sum; ++i) {
int id = s[i] - 'A' + 1;
if (id == 1) numa++;
if (id == 2) numb++;
if (id == 3) numc++;
}
ans = (ans + dfs(1, 0, 0, 1, 1)) % mod;
ans = (ans + dfs(0, 1, 0, 2, 2)) % mod;
ans = (ans + dfs(0, 0, 1, 3, 3)) % mod;
printf("%lld\n", ans);
}
}
山东省第五届ACM省赛 C - Colorful Cupcakes
最新推荐文章于 2018-04-21 16:15:22 发布