HDU 5763 Another Meaning dp+字符串hash || DP+KMP
2016-08-22 19:22
316 查看
题意:给定一个句子str,和一个单词sub,这个单词sub可以翻译成两种不同的意思,问这个句子一共能翻译成多少种不能的意思
例如:str:hehehe sub:hehe 那么,有**he、he**、和hehehe三种不同的意思,
考虑一下aaadaaa这种情况?sub:aa 前面的aaa有三种,后面的aaa有三种,所以一共应该是有9种情况。
可以考虑成3*3=9
如果你考虑分块去相乘的话,那么恭喜你,你GG了。因为这样写非常复杂,而且非常难判断。
可以考虑下dp,因为注意到,它每个单词只有两种状态,要么转换成其他意思,要么就保留原意。
记dp[i]为匹配到str的第i个字符,所拥有的方案数,那么,如果不转换意思,dp[i] = dp[i-1]
就是方案数是没增加的,还是原来拥有的总数。
那么考虑转义。需要str[i-lensub+1...i]这段字符和sub一模一样,你才能转义把?
这里可以用字符串hash的方法O(1)判断
那么dp[i] += dp[i-lenstub];
就是在屏蔽str[i-lensub+1...i]这段字符的情况下,拥有的方案数,+我的转义,就是一种全新的方案,所以匹配到这个字符的时候,方案数要加上屏蔽这段字符前拥有的方案数
View Code
例如:str:hehehe sub:hehe 那么,有**he、he**、和hehehe三种不同的意思,
考虑一下aaadaaa这种情况?sub:aa 前面的aaa有三种,后面的aaa有三种,所以一共应该是有9种情况。
可以考虑成3*3=9
如果你考虑分块去相乘的话,那么恭喜你,你GG了。因为这样写非常复杂,而且非常难判断。
可以考虑下dp,因为注意到,它每个单词只有两种状态,要么转换成其他意思,要么就保留原意。
记dp[i]为匹配到str的第i个字符,所拥有的方案数,那么,如果不转换意思,dp[i] = dp[i-1]
就是方案数是没增加的,还是原来拥有的总数。
那么考虑转义。需要str[i-lensub+1...i]这段字符和sub一模一样,你才能转义把?
这里可以用字符串hash的方法O(1)判断
那么dp[i] += dp[i-lenstub];
就是在屏蔽str[i-lensub+1...i]这段字符的情况下,拥有的方案数,+我的转义,就是一种全新的方案,所以匹配到这个字符的时候,方案数要加上屏蔽这段字符前拥有的方案数
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> using namespace std; #define inf (1<<28) typedef long long int LL; #include <iostream> #include <sstream> #include <vector> #include <set> #include <map> #include <queue> #include <string> const int MOD = 10007; const int maxn = 200000+20; char str[maxn]; void get_next (char sub[],int nextliu[],int len) { nextliu[1]=0; int i=1,j=0; while (i<=len) { if (j==0 || sub[i]==sub[j]) { nextliu[++i]=++j; } else j=nextliu[j]; } return ; } int nextliu[maxn]; int dp[maxn]={0}; void work () { int lenstr; scanf ("%d",&lenstr); scanf ("%s",str+1); get_next(str,nextliu,lenstr); /* for (int i=1;i<=lenstr;i++) { printf ("%d ",next[i]); } printf ("\n");*/ int ans=0; for (int i=1;i<=lenstr;i++) { dp[i]=dp[nextliu[i+1]-1]+1; ans += dp[i]; ans %= MOD; } printf ("%d\n",ans); return ; } int main () { #ifdef local freopen("data.txt","r",stdin); #endif int t; scanf ("%d",&t); while (t--) { work (); } return 0; }
View Code
相关文章推荐
- HDU 4622 Reincarnation(字符串hash,hashMap,区间dp)
- HDU 2594 EX_KMP或者字符串hash
- 【HDU - 4622】Reincarnation 【字符串HASH+dp 】
- [HDU 3336]Count the String[kmp][DP]
- hdu 3374 String Problem (字符串最小最大表示 + KMP求循环节)
- HDU 4295 4 substrings problem [字符串DP]
- hdu 1800 字符串水题 可用字符串hash 字典树做 我用了最水的排序水过
- ZOJ1733 | | HDU1159简单的DP求两个字符串最大子序列的长度,没啥好说的,照着书上敲得。
- hdu 题目1800 Flying to the Mars (Hash字符串 应用)
- HDU 2412 Party at Hali-Bula (树形DP + hash)
- hdu 4552(KMP+DP)
- 多校第二场——hdu4618——字符串hash,二分
- 【hash dp】hdu hdoj 1755 A Number Puzzle
- HDU 3336 Count the string(KMP+dp)
- hdu 3374 String Problem(KMP+字符串最小最大表示)
- hdu 3336 Count the string(KMP+dp)
- hdu 1800 字符串的hash(BKDRHash 模版)大牛推荐的函数
- HDU 3374 KMP +字符串最小表示
- HDU 4295 状态压缩dp + KMP
- HDU 1880 字符串hash 入门题