1222分割字符串

我们定义 (dp_i) 为前 (i) 个字符最长分割的数量,我们发现 (dp_i) 可以从 (dp_j) ((0leq j < i)) 转移过来,并且发现使得 (j) 尽可能大,可以使得往后的转移条件更容易到达(不会表述)

所以我们只需要 (n^2) 就可以辣!

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int read()
{
	int a = 0,x = 1;
	char ch = getchar();
	while(ch > '9' || ch < '0'){
		if(ch == '-') x = -1;
		ch = getchar();
	}
	while(ch >= '0' && ch <= '9'){
		a = a*10 + ch-'0';
		ch = getchar();
	}
	return a*x;
}
const int N=6e2+7;
char s[N];
int dp[N],n;
int sum[N][30];
int f[N][30];

int main()
{
	// freopen("in.in","r",stdin);
	// freopen("out.out","w",stdout);
	scanf("%s",s+1);
	n = strlen(s+1);
	for(int i = 1;i <= n;i ++){
		for(int j = 0;j < 26;j ++){
			sum[i][j] = sum[i-1][j]+(s[i]-'A'==j);
		}
	}
	for(int i = 1;i <= n;i ++){
		for(int j = i-1;j >= 0;j --){
			bool flag = 0;
			for(int k = 0;k < 26;k ++){
				if(sum[i][k]-sum[j][k] < f[j][k]) flag = 1;
			}
			if(flag) continue;
			dp[i] = dp[j]+1;
		//	printf("%d -> %d
",j,i);
			for(int k = 0;k < 26;k ++){
				f[i][k] = sum[i][k]-sum[j][k];
			}
			break;
		}
	}
	printf("%d",dp[n]);
	return 0;
}
原文地址:https://www.cnblogs.com/nao-nao/p/13677704.html