山东省第五届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 cupcakesconsisting 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; }
相关文章推荐
- CodeForces - 552D Vanya and Triangles (数学几何求三角形个数)水
- MediaPlayer+MediaPlayerController+MediaPlayer.OnBufferingUpdateListener实现音乐播放器
- 学习资源(均为转载内容)
- 虚函数与纯虚函数
- ElasticSearch性能优化策略
- 链接/Axis2
- STL中bitset的用法的整理
- 菜鸟入门_Python_机器学习(3)_回归
- 剑指offer之面试题13:在O(1)时间删除链表节点
- [firefox+plug-n-hack]轻松地配置burpsuite代理https流量 - 20160318
- 搭建(win7)eclipse远程操作(Linux上)hadoop2.6.0_出错集
- 反编译流程
- C++面向对象模型
- 焦点事件2016、4、21
- 括号匹配(二) -- 经典动态规划
- CF 552 C. Vanya and Scales
- java时间戳正序和倒序
- 冲刺阶段第二天,4月20日。
- java中功能选项的移除指南(二)
- C 经典 冒泡排序