2031 脑力达人

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值