2021牛客寒假算法基础训练营补题

2021牛客寒假算法基础训练营1补题 - A

题目描述

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

长度不超过nn,且包含子序列“us”的、只由小写字母构成的字符串有多少个? 答案对 10^9+7 取模。
所谓子序列,指一个字符串删除部分字符(也可以不删)得到的字符串。
例如,“unoacscc"包含子序列"us”,但"scscucu"则不包含子序列"us"。

输入描述

一个正整数n (2 <= n <= 1e6)

输出描述

一个正整数,为满足条件的字符串数量对10^9+7取模的值

样例

输入

3

输出

77

说明

长度为3的字符串里,
形状是"u?s"的共有26个
形状是"?us"的共有26个
形状是"us?"的共有26个。
但是,“uss"和"uus"被各多计算了1次,应该减去,
所以共有26*3-2=76个。
再加上长度为2的"us”,所以长度不超过3的合法字符串共有77个

输入

874520

输出

16471619

心路历程

比赛的时候没有做出来,一开始想的是用排列组合的思想,但是会发现有重复的情况,而且重复很难判断有多少个,于是放弃了。赛后看到有用各种dp来写的,本人弱鸡,看的一脸懵逼。晚上ACM集训队大佬分享了一种方法。通过一种找规律的形式,巧妙的AC了,代码量还很少。

规律

把从2 - n长度的字符串的可能性拍成一个三角形,发现如下规律:
在这里插入图片描述
所以长度为 L 的字符串数量应该是由长度为 L-1 的字符串数量乘以 26 再加上 (L-1) 个 25 ^ (L-2) 得到,非常巧妙,大佬nb。

代码如下

#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const ll MOD = 1e9 + 7;

//快速幂
ll power(ll a, ll b)
{
	ll ans = 1;
	while (b > 0)
	{
		if (b & 1)
			ans = ans * a % MOD;
		a = a * a % MOD;
		b >>= 1;
	}
	return ans;
}

int main()
{
	int n;
	cin >> n;
	ll ans = 1, temp = 1;//temp保存当前长度的字符串总数
	for (int i = 1; i < n - 1; i++)
	{
		temp = temp * 26 % MOD + ((i + 1) % MOD * power(25, i) % MOD) % MOD;
		ans = (ans + temp) % MOD;//加上之前的字符串总数得到答案
	}
	cout << ans;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值