牛客練習賽40 A 小D的劇場 (思維dp)
阿新 • • 發佈:2019-02-16
思路 while ram names 方案 音符 contest -i describe
無法觸及,因而耀眼 明明觸及了,卻還是耀眼 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 取模。
星屑飄灑的舞臺上,可人綻放的愛之花,請努力讓大家星光閃耀吧!
鏈接: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+數字,例如輸入描述:
第一行為兩個整數 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; } }
牛客練習賽40 A 小D的劇場 (思維dp)