【KMP】 HDOJ 3613 Best Reward
2014-06-29 15:34
218 查看
做了很久,做不出来,只好看题解了。。。要注意到分割后的两个串是有特点的。前一个串一定包含原始串的第一个字符,后一个串一定包含原始串最后一个字符。如果能注意到就可以应该能想出来了。。。把原始串记为S1, 将原始串翻转记为S2。然后先将S1作为模式串,用S1匹配S2,最后得到的最大匹配就是S1串前缀最长回文串,利用next数组就可以求出所有S1串前缀回文串。。。同样的将S2作为模式串,用S2匹配S1,最后得到的最大匹配就是S1串后缀最长回文串,利用next数组就可以楸树所有S1串后缀回文串。。。。。。最后遍历一遍,算一算最大的价值就行了。。。
#include <iostream> #include <sstream> #include <algorithm> #include <vector> #include <queue> #include <stack> #include <map> #include <set> #include <bitset> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <climits> #define maxn 500005 #define eps 1e-6 #define mod 10007 #define INF 99999999 #define lowbit(x) (x&(-x)) //#define lson o<<1, L, mid //#define rson o<<1 | 1, mid+1, R typedef long long LL; using namespace std; int v[30], len; char s1[maxn], s2[maxn]; int next[maxn]; bool pre[maxn]; bool pos[maxn]; int sum[maxn]; void read(void) { int i, j; for(i = 0; i < 26; i++) scanf("%d", &v[i]); scanf("%s", s1); len = strlen(s1); for(i = 0, j = len-1; i < len; i++, j--) s2[i] = s1[j]; } void init(void) { memset(pre, 0, sizeof pre); memset(pos, 0, sizeof pos); memset(sum, 0, sizeof sum); for(int i = 1; i <= len; i++) sum[i] = sum[i-1] + v[s1[i-1]-'a']; } void get(char *p) { int i, j; next[0] = next[1] = 0; for(i = 1; i <= len; i++) { j = next[i]; while(j && p[i] != p[j]) j = next[j]; next[i+1] = p[i] == p[j] ? j + 1 : 0; } } int kmp(char *p, char *t) { int i, j; for(i = 0, j = 0; i < len; i++) { while(j && t[i] != p[j]) j=next[j]; if(t[i] == p[j]) j++; } return j; } void debug(void) { for(int i = 1; i <= len; i++) { printf("%d\n", sum[i]); } } void work(void) { int i, tmp, ans; get(s1); tmp = kmp(s1, s2); while(tmp) { pre[tmp] = true; tmp = next[tmp]; } get(s2); tmp = kmp(s2, s1); while(tmp) { pos[len - tmp + 1] = true; tmp = next[tmp]; } //debug(); ans = -INF; for(i = 1; i < len; i++) { tmp = 0; if(pre[i]) tmp += sum[i]; if(pos[i + 1]) tmp += sum[len] - sum[i]; if(tmp > ans) ans=tmp; } printf("%d\n", ans); } int main(void) { int _; while(scanf("%d", &_)!=EOF) { while(_--){ read(); init(); work(); } } return 0; }
相关文章推荐
- 扩展kmp入门---hd Best Reward 3613
- hdu 3613 Best Reward 扩展kmp
- hdu 3613 Best Reward 扩展kmp
- HDU 3613 Best Reward 正反两次扩展KMP
- HDU 3613 Best Reward(扩展KMP的应用:回文串判断+扩展KMP模板)
- 扩展KMP --- HDU 3613 Best Reward
- HDU 3613 Best Reward(扩展KMP)
- HDU 3613 Best Reward(扩展KMP模板)
- hdu 3613 Best Reward (扩展KMP)
- HDU 3613 Best Reward(扩展KMP:回文判断)
- HDU 3613 Best Reward(求前后缀回文 拓展KMP or Manacher)
- HDU - 3613 Best Reward(KMP和拓展KMP)
- 扩展KMP --- HDU 3613 Best Reward
- Best Reward (hdu 3613 拓展KMP)
- HDOJ 3613 Best Reward
- hdu 3613 Best Reward (kmp扩展)
- HDU 3613 Best Reward 正反两次扩展KMP
- HDU 3613 Best Reward(扩展KMP)
- HDOJ 3613 Best Reward
- HDU 3613 Best Reward (扩展KMP)