牛客练习赛40 A.小D的剧场
链接:https://ac.nowcoder.com/acm/contest/369/A?&headNav=acm
来源:牛客网
题目描述
"我明白。"
作为这命运剧场永远的观众,小D一直注视着这片星光璀璨的舞台,舞台上,少女们的身姿演绎出了一幕幕动人的场景,令人回味无穷。
有的时候,小D也会自己写一些歌曲,来加入Starlight的剧本,使得剧本充满了新的生命力。
现在小D又要准备写乐谱了,小D写谱的方式比较独特。他会先写出一个按照音符出现顺序排成的序列,再进一步整合,每次整合会选取相邻的三个作为三和弦。整合次数无限。
小D选取的音符形如D5 F6这种形式,例如D5表示D大调sol(这里不考虑升降音)为了方便生成乐谱,他将这些音符进一步转化了,小D给C D E F G A B重新编号成了1 2 3 4 5 6 7,之后新的音符编号生成方式应为(字母对应的标号-1)*7+数字,例如C7=(1−1)×7+7=7C7=(1−1)×7+7=7
但小D讨厌一些他所认为的不优美的和弦,因此他并不希望自己的谱子里面有可能出现这样的三和弦,也就说音符组成的序列里不应该存在他所讨厌的子段,假如C5 F1 A2这三个音符凑成的和弦小D不喜欢,那么序列里面就不能出现C5 F1 A2,C5 A2 F1,A2 C5 F1,A2 F1 C5,F1 A2 C5,F1 C5 A2这六种子段。
现在小D正在推算有多少合法的序列,答案对 109+7109+7 取模。
星屑飘洒的舞台上,可人绽放的爱之花,请努力让大家星光闪耀吧!
输入描述:
第一行为两个整数 n, q ,表示序列的长度和有多少和弦小D不喜欢.
接下来 q 行,每行三个整数 a, b, c ,表示小D不想出现的和弦
输出描述:
一行一个整数,表示答案
示例1
示例2
备注:
3≤n≤500,0≤q≤117649,1≤a,b,c≤49
1 /* 2 f[i][a][b]表示第i位为b,第i-1位为a的合法方案数 3 如果 a b c合法,则 f[i][a][b] = (f[i][a][b] + f[i-1][c][a]) % mod; 4 5 */ 6 #include <bits/stdc++.h> 7 using namespace std; 8 int n,q; 9 bool vis[50][50][50]; 10 int f[510][50][50]; 11 const int mod = 1e9+7; 12 int main(){ 13 scanf("%d%d",&n,&q); 14 for (int i = 0;i < q;++i){ 15 int a,b,c; 16 scanf("%d%d%d",&a,&b,&c); 17 vis[a][b][c] = vis[a][c][b] = vis[b][a][c] = vis[b][c][a] = vis[c][a][b] = vis[c][b][a] = 1; 18 } 19 for (int i = 1;i <= n;++i){ 20 for (int a = 1;a <= 49;++a){ 21 for (int b = 1;b <= 49;++b){ 22 if (i <= 2){ 23 f[i][a][b] = 1; 24 continue; 25 } 26 for (int c = 1;c <= 49;++c){ 27 if (vis[a][b][c]) continue; 28 f[i][a][b] = (f[i][a][b] + f[i-1][c][a]) % mod; 29 } 30 } 31 } 32 } 33 int ans = 0; 34 for (int a = 1;a <= 49;++a){ 35 for (int b = 1;b <= 49;++b){ 36 ans = (ans + f[n][a][b]) % mod; 37 } 38 } 39 printf("%d\n",ans); 40 return 0; 41 }