您的位置:首页 > 其它

山东省第五届ACM大学生程序设计竞赛 Colorful Cupcakes

2016-04-21 20:58 363 查看

Colorful Cupcakes


Time Limit: 2000ms   Memory limit: 65536K  有疑问?点这里^_^

题目描述

Beaver Bindu has N cupcakes. Each cupcake has one of three possible colors. In this problem we will represent the colors by uppercase letters \'A\', \'B\', and \'C\'. Two cupcakes of the same color are indistinguishable. You are given a String cupcakes
consisting of exactly N characters. Each character in cupcakes gives the color of one of Bindu\'s cupcakes.
 
Bindu has N friends, sitting around a round table. She wants to give each friend one of the cupcakes. Moreover, she does not want to give cupcakes of the same color to any pair of friends who sit next to each other.
 
Let X be the number of ways in which she can hand out the cupcakes to her friends. As X can be very large, compute and return the value (X modulo 1, 000, 000, 007).

输入

The first line contains one integer T(1 ≤ T ≤ 60)—the number of test cases. Each of the next T lines contains one string. Each string will contain between 3 and 50 characters, inclusive. Each character in the string will be either \'A\',
\'B\', or \'C\'.

输出

For each test case. Print a single number X — the number of ways in which she can hand out the cupcakes to her friends.
 

示例输入

3
ABAB
ABABA
ABABABABABABABABABABABABABABABABABABABABABABABABAB


示例输出

2
0
2


提示

 

来源

2014年山东省第五届ACM大学生程序设计竞赛

示例程序

 
这几天一直在看区间dp,下意识的相用区间dp做发现不可行,搜了半天才看到一个题解说是用4维dp做

以前没接触过也就想不到用dp【i,a,b,j】来表示第i个小朋友,之前已经吃了a个A蛋糕和b个B蛋糕现在吃第j种蛋糕的方案数(j=1,2,3)(a+b+c=i)

然后枚举第一次吃A OR B OR C蛋糕的情况 然后就是细节问题了

ACcode:

#include <map>
#include <queue>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
#define maxn 55
#define mod 1000000007
#define inf 0x3f3f3f
using namespace std;
/**
所有数据不超过50蛋糕只有3种,4维dp可以搞,枚举A,B吃了多少个,
再枚举这个人吃什么,按照人数从1推到n就可以了,由于人是成环形,
还要注意第n个和第1个人不吃相同的。所以根据第1个人吃什么,
做3遍上述的dp,统计答案就行。
**/
char s[maxn];
int dp[maxn][maxn][maxn][4];///dp[i,a,b,j]到第i个人时候吃了a个蛋糕A蛋糕b个B蛋糕次到j类蛋糕
int num[4],na,nb,nc;///记录每种蛋糕的个数
long long ans;///答案
int main(){
int t;
scanf("%d",&t);
while(t--){
ans=0;
scanf("%s",s+1);
int len=strlen(s+1);
memset(num,0,sizeof(num));
na=num[1]=count(s+1,s+1+len,'A');
nb=num[2]=count(s+1,s+1+len,'B');
nc=num[3]=count(s+1,s+1+len,'C');
for(int loop=1;loop<=3;++loop){
if(num[loop]){
///下面是第一个吃A,B,C蛋糕的初始化
memset(dp,0,sizeof(dp));
if(loop==1)dp[1][1][0][1]=1;
else if(loop==2)dp[1][0][1][2]=1;
else dp[1][0][0][3]=1;
for(int i=2;i<=len;++i)
for(int a=0;a<=min(i,na);++a)
for(int b=0;b<=min(i-a,nb);++b){
int c=i-a-b;
if(a&&((i!=2&&i!=len)||loop!=1))///第i个小朋友吃A蛋糕的情况
dp[i][a][b][1]=(dp[i][a][b][1]+dp[i-1][a-1][b][2]+dp[i-1][a-1][b][3])%mod;
if(b&&((i!=2&&i!=len)||loop!=2))///第i个小朋友吃B蛋糕的情况
dp[i][a][b][2]=(dp[i][a][b][2]+dp[i-1][a][b-1][1]+dp[i-1][a][b-1][3])%mod;
if(c&&((i!=2&&i!=len)||loop!=3))///第i个小朋友吃C蛋糕的情况
dp[i][a][b][3]=(dp[i][a][b][3]+dp[i-1][a][b][1]+dp[i-1][a][b][2])%mod;
}
long long tmp;
tmp=(dp[len][na][nb][1]+dp[len][na][nb][2]+dp[len][na][nb][3])%mod;
ans=(ans+tmp)%mod;
}
}
printf("%lld\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: