[HDU 3336]Count the String[kmp][DP]
来源:互联网 发布:大唐软件 编辑:程序博客网 时间:2024/05/01 10:51
题意:
求一个字符串的所有前缀串的匹配次数之和.
思路:
首先仔细思考: 前缀串匹配.
n个位置, 以每一个位置为结尾, 就可以得到对应的一个前缀串.
对于一个前缀串, 我们需要计算它的匹配次数.
k = next [ j ]
表示前缀串 Sj 的范围内(可以视为较小规模的子问题), 前缀串 Sk 是最长的&能够匹配两次的前缀串.
这和我们需要的答案有什么关系呢?
题目是求所有前缀串的匹配次数之和, 那么可以先求前缀串 Si 在整个串中的匹配次数, 再加和.
到此, 用到了两个"分治", 一是将大规模的问题减小为小规模的问题, 二是将询问的最终结果拆分成一个个步骤, 则专注于分析核心步骤.
可设dp[ i ]为前缀串 Si 在总串中出现的次数.
dp[i] = 1;
dp[next[i]] += dp[i];
#include <cstring>#include <cstdio>const int MAXN = 200005;const int MOD = 10007;int dp[MAXN],next[MAXN];char s[MAXN];//46MS1960Kvoid prekmp(){ next[0] = -1; int j = -1; for(int i=1;s[i];i++) { while(j!=-1 && s[j+1]!=s[i]) j = next[j]; if(s[j+1]==s[i]) j++; next[i] = j; }}int main(){ int T; scanf("%d",&T); while(T--) { int n; scanf("%d",&n); scanf("%s",s); prekmp(); for(int i=0;i<n;i++) dp[i] = 1; dp[n] = 0; for(int i=n-1;i;i--) { if(next[i]!=-1) {dp[next[i]] += dp[i];dp[next[i]] %= MOD;} } for(int i=0;i<n;i++) {dp[n] += dp[i];dp[n] %= MOD;} printf("%d\n",dp[n]); }}
还有另一种思路:
可以将前缀的匹配次数视为包含的前缀个数.
最终的问题是求s中 (设每一种前缀i包含的前缀个数Fi ) ΣFi .
dp[i]为前缀串s[0...i]包含的前缀个数的新增数目(相对于前缀串s[0...i-1]).
则
dp[i] = dp[next[i]] + 1;//1表示它本身也是新增的一个前缀
#include <cstring>#include <cstdio>const int MAXN = 200005;const int MOD = 10007;int dp[MAXN],next[MAXN];char s[MAXN];//62MS1960Kvoid prekmp(){ next[0] = -1; int j = -1; for(int i=1;s[i];i++) { while(j!=-1 && s[j+1]!=s[i]) j = next[j]; if(s[j+1]==s[i]) j++; next[i] = j; }}int main(){ int T; scanf("%d",&T); while(T--) { int n; scanf("%d",&n); scanf("%s",s); prekmp(); memset(dp,0,sizeof(int)*(n+1)); for(int i=0;i<n;i++) { if(next[i]!=-1) { dp[i] = dp[next[i]]+1; dp[i] %= MOD; } else dp[i] = 1; } for(int i=0;i<n;i++) {dp[n] += dp[i];dp[n] %= MOD;} printf("%d\n",dp[n]); }}
- HDU 3336 Count the string(KMP+dp)
- [HDU 3336]Count the String[kmp][DP]
- HDU 3336 Count the string KMP+DP
- hdu 3336 Count the string KMP+DP
- HDU 3336 Count the string kmp+dp
- hdu -- 3336 Count the string(KMP + dp)
- hdu 3336 Count the string 【kmp + dp】
- hdu 3336 Count the string KMP+DP
- HDU 3336(Count the string)DP+KMP
- HDU 3336 Count the string (KMP + DP)
- hdu 3336 Count the string(KMP+dp)
- hdu 3336 Count the string (kmp + dp)
- Hdu-3336 Count the string(KMP + DP)
- HDU 3336 Count the string 【KMP】【dp】
- HDU 3336 Count the string (kmp+dp)
- HDU 3336 Count the string(经典,KMP+DP)
- hdu 3336 Count the string(KMP+dp)
- hdu 3336 Count the string (DP+kmp)
- hdu 4715Difference Between Primes
- Finding Windows CE bugs with help from "Dr. Watson"
- Mysql错误总结
- Kinect for Windows SDK开发入门(十五):进阶指引
- 林彪总结当好师长的“九条经验”
- [HDU 3336]Count the String[kmp][DP]
- 获取当前系统时间
- 在hadoop集群上运行mapreduce程序时报错“org.apache.hadoop.util.Shell$ExitCodeException:***not found”
- js中try/catch/throw的用法
- Java中常见的几种异常
- Identify
- Android应用中,怎么得到全部异常日志
- Ubuntu下关闭进程的方法
- dos下添加和修改ip地址