HDU 3336 Count the string
2015-09-09 01:28
351 查看
题意:问你所有前缀包含本身出现的次数是多少、
首先,不得不在这给大家叙说一个问题,那就是这道题的数据很弱,很多有BUG的代码,也能过、在这,还是希望按照正确的思路,正确的做法来AC这道题、
对于这道题,我本身也是做过了这道题的,其实我刚开始的思路完全错误,不过我AC了、 我朋友在做这道题的时候,问了我一组数据,就是abababab这种情况的时候输出20、
思路:这道题的思路是KMP+DP的思想,那么,首先我们要知道的是,DP只是一种思想,动态规划,是要从曾经求过的不需要重新求取,直接提取出来加入我当前想要求值的,这样降低了时间复杂度,那么KMP呢? 一定能确定的是,KMP用到的也是动态规划的思想、
好,首先一定要了解到next数组的思想、以及两大要素 前后缀相同,和最大循环次数最小循环节的思想、 对于next数组,无需多提,next[i]为在第i个位置前缀与后缀相同的最大值、next[i]里面的不仅为前后缀相同的最大值,也表示了如果当前位置不同,我需要回溯到哪个最优位置来无需匹配我没必要的匹配、
首先我们要知道的是dp[i]里面存的值到底是什么?,dp[i] 表示的意义是,在字符串中第i个位置时,next[i]表示的是我最大的前后缀相同的长度,那么我们可以求解出,这个前后缀出现的次数一定是2次对吧? 而这个前缀,也就是后缀中,也有可能有其他的前缀,在abababab中假设此时i在第三个b的位置时,他的前缀为abab 后缀为abab,此时这个后缀中包含了a,ab,aba,abab 这四个整个字符串的前缀对吧、 那么当我求第i个位置的时候,我只需要找到在dp[i]也就是dp[next[i]]的位置我之前已经求过的前缀中的包含前缀的值、只需在dp[i]也就是dp[next[i]]加上1
变为dp[i]+1=dp[next[i]]+1、 为什么要加上这个1呢? 首先dp[i]表示的是当前前缀时我之前求结果的值,+1也就是加上前缀为0~i 这个整个字符串的子串、
针对 abababab
next[i]-100123456
dp[i] 11223344
答案便为dp中所有的数值相加、 如果自己还不是很理解的话,可以模拟一下,多模拟几次就懂了、无论是怎样学习,当学习新知识的时候,我们都要自己动手来模拟过程,因为这样会更加的使我们的思路清晰,对新知识理解的更深刻、
AC代码:
首先,不得不在这给大家叙说一个问题,那就是这道题的数据很弱,很多有BUG的代码,也能过、在这,还是希望按照正确的思路,正确的做法来AC这道题、
对于这道题,我本身也是做过了这道题的,其实我刚开始的思路完全错误,不过我AC了、 我朋友在做这道题的时候,问了我一组数据,就是abababab这种情况的时候输出20、
思路:这道题的思路是KMP+DP的思想,那么,首先我们要知道的是,DP只是一种思想,动态规划,是要从曾经求过的不需要重新求取,直接提取出来加入我当前想要求值的,这样降低了时间复杂度,那么KMP呢? 一定能确定的是,KMP用到的也是动态规划的思想、
好,首先一定要了解到next数组的思想、以及两大要素 前后缀相同,和最大循环次数最小循环节的思想、 对于next数组,无需多提,next[i]为在第i个位置前缀与后缀相同的最大值、next[i]里面的不仅为前后缀相同的最大值,也表示了如果当前位置不同,我需要回溯到哪个最优位置来无需匹配我没必要的匹配、
首先我们要知道的是dp[i]里面存的值到底是什么?,dp[i] 表示的意义是,在字符串中第i个位置时,next[i]表示的是我最大的前后缀相同的长度,那么我们可以求解出,这个前后缀出现的次数一定是2次对吧? 而这个前缀,也就是后缀中,也有可能有其他的前缀,在abababab中假设此时i在第三个b的位置时,他的前缀为abab 后缀为abab,此时这个后缀中包含了a,ab,aba,abab 这四个整个字符串的前缀对吧、 那么当我求第i个位置的时候,我只需要找到在dp[i]也就是dp[next[i]]的位置我之前已经求过的前缀中的包含前缀的值、只需在dp[i]也就是dp[next[i]]加上1
变为dp[i]+1=dp[next[i]]+1、 为什么要加上这个1呢? 首先dp[i]表示的是当前前缀时我之前求结果的值,+1也就是加上前缀为0~i 这个整个字符串的子串、
针对 abababab
next[i]-100123456
dp[i] 11223344
答案便为dp中所有的数值相加、 如果自己还不是很理解的话,可以模拟一下,多模拟几次就懂了、无论是怎样学习,当学习新知识的时候,我们都要自己动手来模拟过程,因为这样会更加的使我们的思路清晰,对新知识理解的更深刻、
AC代码:
#include<cstdio> #include<cstring> const int maxn=100100*2; const int mod=10007; char T[maxn]; int next[maxn]; int dp[maxn]; int lent,t; int sum; void get_next() { memset(next,0,sizeof(next)); memset(dp,0,sizeof(dp)); int i=0; int j=-1; next[0]=-1; sum=0; while(i<lent){ if(j==-1||T[i]==T[j]) next[++i]=++j; else j=next[j]; } } int main() { scanf("%d",&t); while(t--){ scanf("%d %s",&lent,T); get_next(); for(int i=1;i<=lent;i++){ dp[i]=dp[next[i]]+1; sum+=dp[i]; sum%=mod; } printf("%d\n",sum%mod); } return 0; }
相关文章推荐
- PE49-Prime permutations
- UVA11134_Fabled Rooks
- [LinkerScript.16] SECTION命令: Output Section Address
- 【Python之旅】第二篇(二):列表与元组
- Leetcode Rectangle Area
- Leetcode #202 Happy Number
- UVA1152_4 Values whose Sum is 0
- [AngularJS] Accessing The View-Model Inside The link() When Using controllerAs
- 函数式编程之block
- IBM实习项目经历一【基于jenkins的自动化控制平台】
- Runtime运行时机制
- 基于HT for Web的3D树的实现
- modbus 中CRC16校验
- 块设备驱动程序中request方式和make_request方式的区别(阅读笔记)
- html5 input type number 去掉加减号
- html5 input type number 去掉加减号
- SQL使用in查询按条件顺序返回
- USACO 1.3 Ski Course Design
- 【学习日记】有关java的IO的知识点总结
- 基于HT for Web的3D树的实现