牛客練習賽35 - B背單詞 - 3維的dp
阿新 • • 發佈:2018-12-30
題目描述
winterzz1準備考4級了,現在winterzz1決定把世界上所有單詞都背一遍,winterzz1發現任意一個單詞最多有A個連續的母音,最多有B個連續的子音。且單詞最長長度為N,winterzz1問你在滿打滿算的情況他需要背多少單詞???
輸入描述:
首先輸入一個T(T<=100),表示有T組案例,每組案例依次輸入三個正整數N,A,B,N<=5000,A<=50,B<=50;
輸出描述:
輸出winterzz1最多需要背多少單詞,結果mod(10^9+7)
示例1
輸入
2
2 2 2
500 20 30
輸出
702 175540856
備註:
母音字母為a,e,i,o,u,其餘21個字母均為子音
思路:
開一個dp[5005][2][55]的陣列
dp[i][j][k]:=判斷到第i位,第i位的元素是j(j==0表示母音,j==1表示子音),重複了k次有幾個單詞。
eg、dp[1][0][1]=5。第1位是母音有5種;dp[1][1][1]=21。第1位是子音有21種
dp[2][0][2]=25。第2位是母音,且第1位也是母音有25種。
遞推方程:
for(int j=1;j<=min(b,i-1);j++)dp[i][0][1]=(dp[i][0][1]+dp[i-1][1][j]*5)%mod;
第i位是母音,且第i-1位不是母音的情況,也就是說第i-1位是子音的所有情況之和*5
for(int j=1;j<=min(a,i-1);j++)dp[i][1][1]=(dp[i][1][1]+dp[i-1][0][j]*21)%mod;
第i位是子音,且第i-1位不是子音的情況,也就是說第i-1位是母音音的所有情況之和*21
那麼我們知道動態規劃是由已知到未知的,怎麼賦初值呢?
對於每個i,我們可以求出從母音重複個數從2到a的情況,和子音重複個數為從2到b的情況,然後用遞推方程求出在i位置上之重複1次的情況。
for(int j=2;j<=min(a,i);j++){//初始化,到第i個位置時連續2個母音及以上的情況 dp[i][0][j]=dp[i-1][0][j-1]*5%mod; } for(int j=2;j<=min(b,i);j++){//初始化,到第i個位置時連續2個子音及以上的情況 dp[i][1][j]=dp[i-1][1][j-1]*21%mod; }
(dp小白只能這樣理解了qwq,每次推的時候都懵的一批,不知道怎麼賦初值,不會推qwq)
程式碼如下:
#include<iostream>
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
#include<queue>
#include<cmath>
#include<set>
#include<map>
#include<stack>
#include<sstream>
using namespace std;
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int N=5005,mod=1e9+7;
ll dp[N][2][55];
int main(){
int t,a,b,n;
scanf("%d",&t);
while(t--){
memset(dp,0,sizeof(dp));
scanf("%d%d%d",&n,&a,&b);
dp[1][0][1]=5;dp[1][1][1]=21;
for(int i=2;i<=n;i++){
for(int j=2;j<=min(a,i);j++){
dp[i][0][j]=dp[i-1][0][j-1]*5%mod;
}
for(int j=2;j<=min(b,i);j++){
dp[i][1][j]=dp[i-1][1][j-1]*21%mod;
}
for(int j=1;j<=min(b,i-1);j++)dp[i][0][1]=(dp[i][0][1]+dp[i-1][1][j]*5)%mod;
for(int j=1;j<=min(a,i-1);j++)dp[i][1][1]=(dp[i][1][1]+dp[i-1][0][j]*21)%mod;
}
ll ans=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=a;j++){
ans=(ans+dp[i][0][j])%mod;
}
for(int j=1;j<=b;j++){
ans=(ans+dp[i][1][j])%mod;
}
}
printf("%lld\n",ans%mod);
}
}