题目描述
链接:https://ac.nowcoder.com/acm/contest/9981/A
来源:牛客网
长度不超过n,且包含子序列“us”的、只由小写字母构成的字符串有多少个? 答案对10^9+7取模。
所谓子序列,指一个字符串删除部分字符(也可以不删)得到的字符串。
例如,“unoacscc"包含子序列"us”,但"scscucu"则不包含子序列"us"
输入描述
一个正整数n(2≤n≤1e6)
输出描述
一个正整数,为满足条件的字符串数量对10^9+7取模的值
题解思路
**作者:神崎兰子
链接:https://ac.nowcoder.com/discuss/593200
来源:牛客网
定义dp[i]为长度为i且包含子序列"us"的字符串的数量。
那么对于长度i+1而言,包含子序列"us"的字符串有两类:
①前i个字符已经包含了子序列"us",后面接任意一个字符。数量为dp[i]26
②前i个字符包含字母u,但不包含子序列"us"。后面再接一个字符’s’即可。数量为26i-25i-dp[i]。
两者相加即为dp[i+1]*
在此附上我的AC代码
#include<iostream>
using namespace std;
typedef long long ll;
ll mod=1e9+7;
ll pow_mod(ll a,ll b,ll c){
ll ans = 1;
ll base = a%c;
while(b){
if(b & 1) ans = (ans*base)%c;
base = (base*base)%c;
b >>= 1;
}
return ans;
}
ll n;
ll dp[1000100];
/*
①前i个字符已经包含了子序列"us",后面接任意一个字符。数量为dp[i]*26
②前i个字符包含字母u,但不包含子序列"us"。后面再接一个字符's'即可。数量为26^i-25^i-dp[i]。
2. 全排列 - 不含u字母的 - 有子序列us的。
*/
int main()
{
cin >> n;
dp[1]=0;
dp[2]=1;
for(int i=3;i<=1e6;i++)
dp[i]=(pow_mod(26,i-1,mod)-pow_mod(25,i-1,mod)+25*dp[i-1]+mod)%mod;
ll ans=0;
for(int i=1;i<=n;i++)
ans = (ans+dp[i]%mod)%mod;
cout << ans;
return 0;
}