题解 | #串#

https://ac.nowcoder.com/acm/contest/9981/A

A题题解

思路

使用动态规划。
我们不妨令 L[i] 来表示长度为i的且含序列"us"的字符串的种类
对于L[i]进行集合划分:
① 在第i个字符前“us”已经产生,所以第i个字符可以任意取 => L[i-1]*26
② 在第i个字符时才产生“us”,此时第i个字符一定是‘s’   =>  x[i-1]:长度为i-1的且含‘u’但不含“us”的字符串的种类

 => L[i] = L[i-1]*26 + x[i-1]

所以这就要求我们记录 一个 x 数组
不妨令x[i]:长度为i的且含'u'但不含“us”的字符串的种类
集合划分:
① 在第i个字符前出现过了'u',所以第i个字符取's'以外的字符  => x[i-1]*25
② 在第i个字符时才出现字符‘u’,所以此前一定不含'u'且第i个字符一定为‘u’  => y :长度为i-1的且不含字符‘u’的字符串的种类

 => x[i] = x[i-1]*25 + y

 y = 25^(i-1) 

又因为需要取模,所以我们可以得到如下的式子:
(1) L[i] = (L[i-1]*26 + x[i-1])%MOD 
(2) x[i] = (x[i-1]*25 + 25^(i-1))%MOD


综上 Code如下:

code

#include <iostream>
#include <algorithm>

using namespace std;

const int N=1e6+10;
const int MOD=1e9+7;

typedef long long ll;

ll x[N];
ll L[N];
ll ans;
int n;

/*
x[i]:长度为i的且含‘u’但不含“us”的字符串的种类
L[i]:长度为i的且含"us"的字符串的种类
*/

ll qpow(ll a,ll b){
    ll base=a%MOD;
    ll res=1;

    while(b){
      if(b&1) res=(res*base)%MOD;
      base=(base*base)%MOD; 
      b>>=1;   
    }

    return res;   
}

int main(){
    cin>>n;

    x[1]=1; // x数组初始化
    for(int i=2;i<=n;i++){
       L[i] = (L[i-1]*26 + x[i-1]) % MOD ;
       x[i] = (x[i-1]*25 + qpow(25,i-1)) % MOD ;
       ans = (ans + L[i]) % MOD;
    }        

    cout<<ans<<endl;    

    return 0;
}
全部评论

相关推荐

2025-12-30 14:09
已编辑
北京交通大学 算法工程师
字节跳动 训练框架研发 (N+2) * (12 + 3) 硕士211
Crinton:训练框架遥遥领先
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
2025-11-19 14:56
点赞 评论 收藏
分享
评论
3
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务