2031 脑力达人
其实动态规划真的在解决字符串上是很牛的,kmp其实就是一种基于动态规划的东西
给定一个现有的字符串进行拆分 给定一个字典序,要求每一个子串都必须要包含其中的任意一个单词
好像很简单,但是还是不理解什么意思
这个题的题解数量少的可怜,网上的题解还大多数是踹(trie)我没什么本事,不会
所以,我把这一篇想了很久
首先,我们最外边的循环枚举每一个总串的长度
然后再枚举每一个字典序,再枚举他的每一位
再枚举总串的每一个分割的可能和当前的字典序进行比较,如果只要发现比较不行了
就直接退出,保证前面比较成功的长度
然后就能更新f数组了,f数组的定义自然就是题目中我们要求的
f[k]=max(f[k],f[i-1]+1)
也就是对于每一个可以分割的串,都是以i为开端的,所以还需要再加1
然后就没了
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int f[310];
int main()
{
int i,n,l;
bool x;
char s[310],si[510][310];
scanf("%s%d",s,&n);
for (i=1;i<=n;i++)
scanf("%s",si[i]);
l=strlen(s);
for (i=0;i<l;i++)//枚举总的长串
{
for (int j=1;j<=n;j++)//枚举每一个字典串
{
int len=strlen(si[j]);//枚举每一个字串
if (l-i<len) continue;//两个比较的字符串还不够长度,所以肯定没法匹配
x=true;
for (int k=0;k<len;k++)//枚举子串的每一位
{
if (s[k+i]!=si[j][k])//s[k+i]表示枚举每一个可以分割的子串,si[j][k]表示每一个字典序的每一个字母
{
x=false;//不满足字典序
break;//不满足直接停止
}
}
if(x)//表示可以分割子串
{
for (int k=i+len-1;k<l;k++)//依次长度全部更新
{
if (i==0) f[k]=max(f[k],1);//表示只有一位的时候,不需要更新
else f[k]=max(f[k],f[i-1]+1);
}
}
}
}
cout<<f[l-1];
return 0;
}