【NOIP模拟赛】【乱搞AC】【奇技淫巧】【乘法原理】回文串计数
2016-10-24 22:44
239 查看
回文串计数
(calc.pas/calc.c/calc.cpp)
【题目描述】
虽然是一名理科生,Mcx常常声称自己是一名真正的文科生。不知为何,他对于背诵总有一种莫名的热爱,这也促使他走向了以记忆量大而闻名的生物竞赛。然而,他很快发现这并不能满足他热爱背诵的心,但是作为一名强大的Boer,他找到了这么一条自虐的方式——背诵基因序列。不过这实在是太虐心了,就连Mcx也有些招架不住。不过他发现,如果他能事先知道这个序列里有多少对互不相交的回文串,他或许可以找到记忆的妙法。为了进一步验证这个方法,Mcx决定选取一个由小写字母构成的字符串SS来实验。不过由于互不相交的回文串实在过多,他很快就数晕了。不过他相信,在你的面前这个问题不过是小菜一碟。【名词解释】
1.对于字符串SS,设其长度为Len,那么下文用Si表示SS中第i个字符(1<=i<=Len)2.s[i,j]表示SS的一个字串,s[i,j] = “SiSi+1Si+2…Sj-2Sj-1Sj”,比如当SS为”abcgfd”时,
s[2,5] = “bcgf” , s[1,5] = “abcgf”
3.当一个串被称为一个回文串当且仅当将这个串反写后与原串相同,如”abcba”
4.考虑一个四元组(l,r,L,R) , 当s[l,r]和s[L,R]均为回文串时,且满足1 <= l <=r< L <= R <= Len时,我们称s[l,r]和s[L,R]为一对互不相交的回文串。也即本题所求即为这种四元组的个数。两个四元组相同当且仅当对应的l,r,L,R都相同。
【题目输入】
仅一行,为字符串SS,保证全部由小写字母构成,由换行符标志结束。【题目输出】
仅一行,为一个整数,表示互不相交的回文串的对数。【样例输入】
aaa【样例输出】
5【样例解释】
SS = “aaa” , SS的任意一个字串均为回文串,其中总计有5对互不相交的回文串:(1,1,2,2) , (1,1,2,3) , (1,1,3,3) , (1,2,3,3) , (2,2,3,3). (这里使用名词解释中的四元组进行表示)
【数据范围】
50%的数据满足SS的长度不超过200100%的数据满足SS的长度不超过2000
【Solution】
先吐槽一下这题的数据,O(N3)的大暴力过了90%的点....当然下面讲的是AC做法。首先用区间DP求出ch[i]到ch[j]之间是不是回文串,转移方程为pldr[i][j]=pldr[i+1][j-1],注意特判i==j和j-i+1==2的情况。然后N2求出每个字符之前(包括他自己)共有多少个回文字符串,再用N2求出每个字符之后 以这个字符相邻(去重)的字符为起点的回文字符串数量。最后N求出每个点之前的数目乘上之后的数目(乘法原理)的总和,即为答案。
AC代码:
#include <cstdio> #include <cstring> #include <iostream> using namespace std; char ch[2010]; bool pldr[2010][2010]; int lenn; int bef[2010],aft[2010]; long long ans; int main(){ scanf("%s",ch+1); lenn=strlen(ch+1); for(int i=1;i<=lenn;++i) pldr[i][i]=true; for(int i=lenn;i>=1;--i) for(int j=i;j<=lenn;++j) if(j>=i&&ch[i]==ch[j]){ if(i==j) pldr[i][j]=true; else if(j-i+1==2)pldr[i][j]=true; else pldr[i][j]=pldr[i+1][j-1]; } for(int i=1;i<=lenn;++i){ bef[i]=bef[i-1]; for(int j=1;j<=i;++j) if(pldr[j][i]) ++bef[i]; } for(int i=1;i<lenn;++i) for(int j=i;j<=lenn;++j) if(pldr[i+1][j]) ++aft[i]; for(int i=1;i<=lenn;++i) ans+=bef[i]*aft[i]; printf("%I64d",ans); return 0; }
相关文章推荐
- [NOIP模拟赛][并没有用二分][乱搞AC]
- 【NOIP模拟赛】【乱搞AC】【贪心】【模拟】匹配
- 【NOIP模拟赛】beautiful 乱搞(平衡树)+ST
- NOI.AC NOIP模拟赛 第二场 补记
- 【NOIP 模拟赛】区间第K大(kth) 乱搞
- [noip模拟赛]中位数(乱搞)
- NOI.AC NOIP模拟赛 第六场 游记
- NOI.AC NOIP模拟赛 第五场 游记
- NOI.AC NOIP模拟赛 第三场 补记
- NOI.AC NOIP模拟赛 第四场 补记
- NOI.AC NOIP模拟赛 第一场 补记
- noip模拟赛 捡金币
- 2016.09.03【初中部 NOIP提高组 】模拟赛C
- 【NOIP模拟赛】正方形大阵
- noip模拟赛 写代码
- 【NOIP2016复赛模拟赛2】遭遇战
- 2017.5.27 NOIP模拟赛(hzwer2014-5-16 NOIP模拟赛)
- noip模拟赛 分组
- 【不知道是啥的NOIP模拟赛】网络入侵
- 2017.06.24【NOIP提高组】模拟赛B组