2021牛客寒假算法基础集训营1 A-串(dp推状态)

题目链接:点这里~

题目大意

  • 长度不超过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;
}

猜你喜欢

转载自blog.csdn.net/weixin_43911947/article/details/113530180
今日推荐