题意
给一个数字n,然后设计一个字符串,至少包含三个shs
,shshs
算一个
必须是shs...shsshs
才算三个,求方案数目
解法
状态机dp,设dp[i][j]
表示前i个字符,并且最后一个字符匹配shsshsshs
中的第j位的方案数目
状态转移
显然从第i层向i+1层容易
#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
int dp[1000010][10];//第二维度只包含s,sh,shs三种情况
int main(){
int n;
scanf("%d",&n);
dp[0][0]=1;//定义初始状态
for(int i=0;i<n;i++){
for(int j=0;j<10;j++){
if(j==9){//刚好组成3个shs
dp[i+1][j]=(dp[i+1][j]+26ll*dp[i][j])%mod;//下一个状态由当前状态乘26所得
}
else if(j%3==1){//以s结尾
dp[i+1][j]=(dp[i+1][j]+dp[i][j])%mod;//s后加的字符仍为s ,第二维度仍为j
dp[i+1][j+1]=(dp[i+1][j+1]+dp[i][j])%mod;//s后加的字符为h,变为第二种情况以sh结尾,第二维度变为j+1
dp[i+1][j/3*3]=(dp[i+1][j/3*3]+24ll*dp[i][j])%mod;//s后加的字符为除s和h外的任意24个字符,重新变为整shs的情况
}
else {//以sh和以其他字符结尾的一起讨论 此时j可能为0可能为2
dp[i+1][j+1]=(dp[i+1][j+1]+dp[i][j])%mod;//以sh为结尾的情况下可以选择以s为结尾,下一个状态就直接加上dp[i][j] 或者 以其他字符为结尾的情况下选择以s为结尾
dp[i+1][j/3*3]=(dp[i+1][j/3*3]+25ll*dp[i][j])%mod; //以sh为结尾的情况下加上了除s外的其他字符,重新变为整shs的情况 或者 以其他字符为结尾的情况下再选择以其他字符结尾
}
}
}
printf("%d\n",dp[n][9]);//最后输出的是刚好有3个shs的情况,所以第二维度为9
}