51Nod 1277 - 字符串中的最大值(KMP)

【题目描述】
《51Nod 1277 - 字符串中的最大值(KMP)》

【思路】
假设现在有一个位置 p o s pos pos ,其前缀已经出现一次即 [ 0 , p o s − 1 ] [0,pos-1] [0,pos1] 这个前缀已经出现了一次,现在考虑一下 n e x t [ p o s ] next[pos] next[pos] 的意义,其实就是包含在 [ 0 , p o s − 1 ] [0,pos-1] [0,pos1] 这个前缀里面的前缀(前缀针对整个字符串而言,并非 [ 0 , p o s − 1 ] [0,pos-1] [0,pos1] 这个子串),也就是如果我们能够知道一个前缀出现的次数,那么包含在这个前缀里面的前缀也应当又出现了一次,所以只要跑一遍 KMP 得到 n e x t next next 数组,然后对每一个前缀出现的次数都叠加到其包含的前缀当中去,即状态转移方程 d p [ n e x t [ i ] ] + = d p [ i ] dp[next[i]] += dp[i] dp[next[i]]+=dp[i] ( d [ i ] d[i] d[i] 代表长度为 i i i 的前缀出现的次数),整个过程应该是逆推的

#include<bits/stdc++.h>
using namespace std;

const int maxn=100005;

char p[maxn];
int nxt[maxn],lenp;
long long dp[maxn];

void getnext(){
	nxt[0]=-1;
	int j=0,k=-1;
	while(j<lenp){
		if(k==-1 || p[k]==p[j]){
			++j;
			++k;
			nxt[j]=k;
		}
		else k=nxt[k];
	}
}

int main(){
	scanf("%s",p);
	lenp=strlen(p);
	getnext();
	for(int i=1;i<=lenp;++i) dp[i]=1;
	for(int i=lenp;i>=1;--i) dp[nxt[i]]+=dp[i];
	long long ans=0;
	for(int i=1;i<=lenp;++i) ans=max(ans,(long long)i*dp[i]);
	printf("%lld\n",ans);
	return 0;
}
    原文作者:KMP算法
    原文地址: https://blog.csdn.net/xiao_k666/article/details/83832516
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞