2022HBCPC 优美的字符串
admin
2024-01-17 22:50:03

优美的字符串

题目描述

我们称一个字符串是优美的,当且仅当这个字符串中不存在长度严格大于 2 的回文串。

现在有 m 种不同的字符,那么在可以组成的长度恰好为 nm^n 个不同的字符串中,请求出一共有多少个字符串是优美的,输出答案对 1000000007 取模后的结果即可。

题目分析

字符串中不能存在严格大于2的回文串,则每相邻的三个字符都不能是回文串。三个字符非回文的情况有三aab abb abc。围绕此三种情况进行思考即可。

可以向动态规划的思想上靠拢(当时也没怎么往这边想

定义集合f[i][3]:
f[i][0]:以i结尾,最后三个字符为 abc类的方案的集合
f[i][1]:以i结尾,最后三个字符为 aab类的方案的集合
f[i][2]:以i结尾,最后三个字符为 abb类的方案的集合

根据三种状态的特点我们可以得到状态转移方程

f[i][0] = f[i - 1][1] * (m - 2) + f[i - 1][0] * (m - 2)
f[i][1] = f[i - 2][0] * (m - 2) 
f[i][2] = f[i - 1][0] + f[i - 1][1];

值得注意的是,当n<3时的情况需要特判

  • n == 1时,方案数为m
  • n == 2时,方案数为 m + m * (m - 1) 即m * m
    • 类似aa bb 也为合法方案,即为第一个 m
    • 从m个数中任意选择两个,即为 m*(m-1)

值得注意的是取模一定要细心

code

#includeusing namespace std;const int N = 1e6 + 10, mod = 1000000007;
typedef long long ll;ll n, m, k, t;
ll f[N][3];int main()
{cin >> n >> m;if(n < 3){if(n == 1) cout << m << "\n";else{ll ans = m * m % mod;cout << ans % mod << "\n";}return 0;}f[3][0] = m * (m - 1) % mod * (m - 2) % mod;f[3][1] = f[3][2] = m * (m - 1) % mod;for(int i = 4; i <= n; i ++){f[i][0] = (f[i - 1][1] * (m - 2)) % mod + (f[i - 1][0] * (m - 2) % mod);f[i][1] = f[i - 1][2] * (m - 2) % mod;f[i][2] = (f[i - 1][0] % mod) + (f[i - 1][1] % mod) % mod;}cout << (f[n][0] + f[n][1] + f[n][2]) % mod << "\n";return 0;
}

上一篇:上峰寺两首歌之一

下一篇:感受三首歌

相关内容

热门资讯

曹操有25个儿子,为何还让司马... 曹操有25个儿子,为何还让司马懿夺了权?只因一个致命弱点?下面趣历史小编为大家详细介绍一下相关内容。...
汉武帝宁愿杀了大侠郭解,为何也... 今天趣历史小编为大家带来了一篇关于汉武帝的文章,欢迎阅读哦~匈奴的崛起,与汉民族走向统一,几乎是在同...
揭秘:为什么魏晋名士那么爱喝酒... 今天趣历史小编为大家带来了一篇关于魏晋的文章,欢迎阅读哦~魏晋风度在我国历史上是个非常有名的文学语码...
慈禧守寡是才26岁 她是怎么度... 还不知道:慈禧守寡是怎么度过深宫的生活的读者,下面趣历史小编就为大家带来详细介绍,接着往下看吧~慈禧...
《三国》五虎上将,去掉一个让魏... 《三国》五虎上将,去掉一个让魏延顶替,换掉谁更合适?下面趣历史小编为大家详细介绍一下相关内容。在看小...