题意:一个长为n的字符串,字符的组成全是小写英文字母,给出26个英文字母的所在分割字符串的长度范围,将字符串分割,问有多少种分割方法,分割后最长字符串的长度,最少的分割个数。
分析:dp[i]代表到i位置的分割方法数,那么 当第i个位置到第j个位置能形成一个分割字符串时,dp[i]+=dp[j].
类似的分割方法数的题目都能这样去做。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <string>
using namespace std;
typedef long long ll;
const int INF=0x3f3f3f3f,N=1005,mod=1e9+7;
int a[26],dp[N]={0},dp1[N]={0},dp2[N];
int main()
{
int n;
char s[1005];
scanf("%d%s",&n,s);
memset(dp2,INF,sizeof(dp2));
for(int i=0;i<26;i++)
scanf("%d",&a[i]);
dp[0]=1;
dp2[0]=0;
for(int i=1;i<=n;i++)
{
int len=INF;
for(int j=i-1;j>=0;j--)
{
len=min(len,a[s[j]-'a']);
if(i-j>len) break;
dp[i]+=dp[j],dp[i]%=mod;
dp1[i]=max(dp1[i-1],i-j);
dp2[i]=min(dp2[i],dp2[j]+1);
}
}
printf("%d\n%d\n%d\n",dp[n],dp1[n],dp2[n]);
}