链接:https://ac.nowcoder.com/acm/contest/9981/A
来源:牛客网
串
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
长度不超过nn,且包含子序列“us”的、只由小写字母构成的字符串有多少个? 答案对10^9+710
9
+7取模。
所谓子序列,指一个字符串删除部分字符(也可以不删)得到的字符串。
例如,“unoacscc"包含子序列"us”,但"scscucu"则不包含子序列"us"
输入描述:
一个正整数nn(2 \leq n \leq 10^62≤n≤10
6
)
输出描述:
一个正整数,为满足条件的字符串数量对10^9+710
9
+7取模的值
示例1
输入
复制
2
输出
复制
1
说明
仅有“us”这一个字符串合法
示例2
输入
复制
3
输出
复制
77
说明
长度为3的字符串里,
形状是"u?s"的共有26个
形状是"?us"的共有26个
形状是"us?"的共有26个。
但是,“uss"和"uus"被各多计算了1次,应该减去,
所以共有26*3-2=76个。
再加上长度为2的"us”,所以长度不超过3的合法字符串共有77个。
示例3
输入
复制
874520
输出
复制
16471619
dp[i][0]表示长度为i的串不含有u,
那么不含有u就有25个字符可选
dp[i][0]=dp[i-1][0]*25;
dp[i][1]则是含有u但是不含us
那么不含s就有25个字符可选+前面不含u的情况
dp[i][1]=dp[i-1][1]*25+dp[i-1][0];
dp[i][2]含有us的情况
接下来的这一位就有26种情况选择,加上前面只含u的当前为s那么也满足情况。
dp[i][2]=dp[i-1][2]*26+dp[i-1][1];
为什么要考虑含不含有u,s,us呐,为了避免重复,我们就考虑当前一位的情况即可,不用担心有重复。
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6;
const int N=35;
int w[N];
int g[N][N],f[N][N];
typedef long long ll;
const int p=1e9+7;
void dfs(int l,int r)
{
if(l>r)
return;
int k=g[l][r];
cout<<g[l][r]<<" ";
dfs(l,k-1);
dfs(k+1,r);
}
ll dp[maxn][3];
int main()
{
int n;
cin>>n;
ll ans=0;
dp[1][0]=25;
dp[1][1]=1;
dp[1][2]=0;
for(int i=2;i<=n;i++)
{
dp[i][0]=dp[i-1][0]*25%p;//不含有u,那么还剩下25个字符随便选
dp[i][1]=(dp[i-1][1]*25+dp[i-1][0])%p;//含有u,但不含us,可以是本来含有u,那么还有25个除s的字符可选加上以u结尾的前面不含u的
dp[i][2]=(dp[i-1][2]*26+dp[i-1][1])%p;//含us那么当前位有26个可选,或者前面含有u,当前位以s结尾
ans=(ans+dp[i][2])%p;
}
cout<<ans<<endl;
return 0;
}