链接:https://ac.nowcoder.com/acm/contest/9981/A
来源:牛客网


时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
长度不超过nn,且包含子序列“us”的、只由小写字母构成的字符串有多少个? 答案对10^9+710
9
+7取模。
所谓子序列,指一个字符串删除部分字符(也可以不删)得到的字符串。
例如,“unoacscc"包含子序列"us”,但"scscucu"则不包含子序列"us"
输入描述:
一个正整数nn(2 \leq n \leq 10^62≤n≤10
6

输出描述:
一个正整数,为满足条件的字符串数量对10^9+710
9
+7取模的值
示例1
输入
复制
2
输出
复制
1
说明
仅有“us”这一个字符串合法
示例2
输入
复制
3
输出
复制
77
说明
长度为3的字符串里,
形状是"u?s"的共有26个
形状是"?us"的共有26个
形状是"us?"的共有26个。
但是,“uss"和"uus"被各多计算了1次,应该减去,
所以共有26*3-2=76个。
再加上长度为2的"us”,所以长度不超过3的合法字符串共有77个。
示例3
输入
复制
874520
输出
复制
16471619

dp[i][0]表示长度为i的串不含有u,
那么不含有u就有25个字符可选

dp[i][0]=dp[i-1][0]*25;
dp[i][1]则是含有u但是不含us
那么不含s就有25个字符可选+前面不含u的情况
dp[i][1]=dp[i-1][1]*25+dp[i-1][0];

dp[i][2]含有us的情况
接下来的这一位就有26种情况选择,加上前面只含u的当前为s那么也满足情况。
dp[i][2]=dp[i-1][2]*26+dp[i-1][1];
为什么要考虑含不含有u,s,us呐,为了避免重复,我们就考虑当前一位的情况即可,不用担心有重复。

#include <iostream>
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6;
const int N=35;
int w[N];
int g[N][N],f[N][N];
typedef long long ll;
const int p=1e9+7;
void dfs(int l,int r)
{
    if(l>r)
        return;
    int k=g[l][r];
    cout<<g[l][r]<<" ";
    dfs(l,k-1);
    dfs(k+1,r);
}
ll dp[maxn][3];
int main()
{
   int n;
   cin>>n;
  ll ans=0;
  dp[1][0]=25;
  dp[1][1]=1;
  dp[1][2]=0;
  for(int i=2;i<=n;i++)
  {
      dp[i][0]=dp[i-1][0]*25%p;//不含有u,那么还剩下25个字符随便选
      dp[i][1]=(dp[i-1][1]*25+dp[i-1][0])%p;//含有u,但不含us,可以是本来含有u,那么还有25个除s的字符可选加上以u结尾的前面不含u的
      dp[i][2]=(dp[i-1][2]*26+dp[i-1][1])%p;//含us那么当前位有26个可选,或者前面含有u,当前位以s结尾
      ans=(ans+dp[i][2])%p;
  }
  cout<<ans<<endl;
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值