题解 | #串#

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;
}
全部评论

相关推荐

11-07 13:31
怀化学院 Java
勇敢牛牛不怕难:又疯一个
点赞 评论 收藏
分享
Noob1024:一笔传三代,人走笔还在
点赞 评论 收藏
分享
3 收藏 评论
分享
牛客网
牛客企业服务