题目链接:点这里~
题目大意
- 长度不超过n,且包含子序列“us”的、只由小写字母构成的字符串有多少个? 答案对1e9+7取模。
- 子序列,us可以不相邻
- 范围:2≤n≤1e6
思路
- 用dp转移状态。如果要看数学推公式的 点这里~
- 定义:dp[i][0]表示长度为i的串没有u,dp[i][1]表示长度为i的串有u但没有s,dp[i][2]表示长度为i的串有us子序列。
- 初始化:dp[1][0] = 25, dp[1][1] = 1, dp[1][2] = 0.
- 状态转移:dp[i][0] = dp[i - 1][0] * 25(之前没有u,当前位也不选u)
- dp[i][1] = dp[i - 1][0](之前没有u,当前位选u) + dp[i - 1][1]*25(之前已经选了u但没有s,当前位也不选s)
- dp[i][2] = dp[i - 1][1](之前有u无s,当前位选s) + dp[i - 1][2] * 26(之前已经有us了,所以当前位随便选)
- 长度不超过n,所以dp[i][2]都是满足要求的
ac代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int mod = 1e9 + 7;
const int maxn = 1e6 + 5;
ll dp[maxn][5];
int main(){
int n; cin >> n;
dp[1][0] = 25; //无u
dp[1][1] = 1; //有u无s
dp[1][2] = 0; //有us
ll ans = 0;
for(int i = 2; i <= n; i ++){
dp[i][0] = dp[i - 1][0] * 25 % mod;
dp[i][1] = (dp[i - 1][0] + dp[i - 1][1] * 25 % mod) % mod;
dp[i][2] = (dp[i - 1][1] + dp[i - 1][2] * 26 % mod) % mod;
ans = (ans + dp[i][2]) % mod;
}
cout << ans << endl;
return 0;
}