博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【2019 1月集训 Day1】回文的后缀
阅读量:5169 次
发布时间:2019-06-13

本文共 1040 字,大约阅读时间需要 3 分钟。

题意:

  给定 n,s,求有多少个字符集大小为 s ,长度为 n 的字符串,使得其不存在一个长度大于 1 回文后缀

  答案对 m 取模。

分析:

  考场见到计数题的链式反应,想写暴力—>暴力难写—>不会暴力—>弃疗—>爆零。

  今天考试也不例外。但是逐渐思想过于摸化,没想到今天T2这么简单的一个递推,竟然不会写,我好弱啊,大概是学废了。

  对于这道题目,我们想到,后缀其实就是前缀(把字符串倒过来即可)我们设f[i]表示长度为i的满足题意的最长回文前缀是1的字符串有多少个,f[0]=1,在转移时,我们啥都不考虑,直接加一个字母。

  但是可能原串是这样的,最长回文前缀长度为1,我们加了一个字母之后,突然最长回文前缀长度就变成了i,比如“abbbbbb”最长回文前缀是1,但是,假如我们加入一个a,那么这个长度立刻就变成了8,我们就要把不和法的减去,所以考虑长度为p的回文串(不存在一个大于1的回文串是它的前缀)的数目,其实我们把把半个串确定了,整个回文串就确定了。

  所以方案数是f[ceil(i/2)],(ceil()函数代表向上取整)。

  最终的递推式子就是f[i]=f[i-1]*s-f[ceil(i/2)];

  别忘取模……

代码:

 

1 #include
2 #include
3 #include
4 #include
5 #include
6 #define ll long long 7 using namespace std; 8 const int N=10000005; 9 ll f[N],m,n,k,s,w;10 int main(){11 scanf("%lld%lld%lld",&n,&s,&m);12 f[0]=1;for(int i=1;i<=n;i++)13 f[i]=(f[i-1]*s-f[(i+1)>>1])%m;14 printf("%lld\n",f[n]%m);15 return 0;16 }
dp

 

转载于:https://www.cnblogs.com/Alan-Luo/p/10209075.html

你可能感兴趣的文章
Apriori算法
查看>>
onlevelwasloaded的调用时机
查看>>
lr_start_transaction/lr_end_transaction事物组合
查看>>
CodeIgniter学习笔记(四)——CI超级对象中的load装载器
查看>>
.NET CLR基本术语
查看>>
ubuntu的home目录下,Desktop等目录消失不见
查看>>
建立,查询二叉树 hdu 5444
查看>>
[Spring框架]Spring 事务管理基础入门总结.
查看>>
2017.3.24上午
查看>>
Python-常用模块及简单的案列
查看>>
LeetCode 159. Longest Substring with At Most Two Distinct Characters
查看>>
基本算法概论
查看>>
jquery动态移除/增加onclick属性详解
查看>>
JavaScript---Promise
查看>>
暖暖的感动
查看>>
Java中的日期和时间
查看>>
Django基于admin的stark组件创建(一)
查看>>
C. Tanya and Toys_模拟
查看>>
springboot jar包运行中获取资源文件
查看>>
基于FPGA实现的高速串行交换模块实现方法研究
查看>>