链接:https://ac.nowcoder.com/acm/contest/369/A
题目描述
若你摘得小的星星 你将得到小的幸福
若你摘得大的星星 你将得到大的财富
若两者都能摘得 你将得到永远的愿望
摘星是罪孽的宽恕 摘星是夜晚的奇迹
抓住它吧 你所期望的那颗星
无法触及,因而耀眼
明明触及了,却还是耀眼
——《少女☆歌剧 Revue·Starlight》
题目描述
"我明白。"
作为这命运剧场永远的观众,小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
输入
10 10 18 3 3 43 28 22 42 28 3 48 48 4 29 9 31 47 9 22 1 22 49 15 48 29 2 8 27 4 24 34
输出
382785822
题意:给你一个序列长度n,现在每一个位置都有49种方案可以填入,再给出q种不合法的方案 问有多少种可行方案
结果对1e9+7取模
思路: dp[i][k][l] 表示第i各位置放置 k和l两种音符 我们只需要枚举49^3种情况 对于 j k l 可行的情况 我们就有递推式
dp[i][k][l]+=dp[i-1][j][k]
其实这么看来问题就没那么复杂了
#include <cstdio> #include <map> #include <iostream> #include<cstring> #include<bits/stdc++.h> #define ll long long int #define M 6 using namespace std; inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} inline ll lcm(ll a,ll b){return a/gcd(a,b)*b;} int moth[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; int dir[4][2]={1,0 ,0,1 ,-1,0 ,0,-1}; int dirs[8][2]={1,0 ,0,1 ,-1,0 ,0,-1, -1,-1 ,-1,1 ,1,-1 ,1,1}; const int inf=0x3f3f3f3f; const ll mod=1e9+7; int n,q; ll dp[507][57][57]; //dp[i][k][l] 表示第i各位置放置 k和l两种音符 int a[50][50][50]; int main(){ ios::sync_with_stdio(false); while(cin>>n>>q){ memset(a,0,sizeof(a)); for(int i=1;i<=q;i++){ int ta,tb,tc; cin>>ta>>tb>>tc; a[ta][tb][tc]=1; a[ta][tc][tb]=1; a[tb][ta][tc]=1; a[tb][tc][ta]=1; //对不可行方案进行标记 a[tc][ta][tb]=1; a[tc][tb][ta]=1; } for(int i=1;i<=2;i++) for(int j=1;j<=49;j++) for(int k=1;k<=49;k++) //初始化 dp[i][j][k]=1; for(int i=3;i<=n;i++) for(int j=1;j<=49;j++) for(int k=1;k<=49;k++) for(int l=1;l<=49;l++){ if(a[j][k][l]) continue; dp[i][k][l]=(dp[i][k][l]+dp[i-1][j][k])%mod; //如果是可行方案则 jk的后面就可以是l } ll ans=0; for(int i=1;i<=49;i++) for(int j=1;j<=49;j++){ ans=(ans+dp[n][i][j])%mod; } cout<<ans<<endl; } }