POJ 3267 The Cow Lexicon DP 字符串匹配问题扩展

POJ 3267 The Cow Lexicon    DP 字符串匹配问题扩展


<strong><span style="font-size:18px;">/*题意:给一个主串 和n个子串  问最少在主串删除多少字母,可以使其匹配到 n 个单词序列中的一些

思路:dp[i]  表示从主串开头的字母到第 i  个字母最少需要删除字符的个数(即主串长度为i时)

d[i]=min( d[j]+dele       //如果S[j+1..i]子串中包含了一个单词,j<=i  
                d[i-1]+1 )      //如果不存在可包含单词的子串| 最坏情况

 dele为要删的字符的个数  dele=匹配位置-终止位置-单词长度
*/</span></strong>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
char s[400];
char ss[650][30];
int len[650];
int dp[400];
int main()
{
    int n,L;
    while(~scanf("%d%d",&n,&L))
    {
        scanf("%s",s);
        for(int i=1; i<=n; i++)
        {
            scanf("%s",ss[i]);
            len[i]=strlen(ss[i]);
        }
        for(int i=0; i<L; i++)
        {
            if(!i)
                dp[i]=1;
            else
                dp[i]=dp[i-1]+1;      //最坏的情况
            for(int k=1; k<=n; k++)
            {           //从i开始查找匹配
                int lenth=len[k]-1,j=i,dele=0;
                while(lenth>=0&&j>=0&&j-lenth>=0)
                {
                    if(s[j]==ss[k][lenth])
                        lenth--;
                    j--;
                }
                if(lenth<0)   //只有整个单词都匹配了   才进行改变
                {
                    dele=i-j-len[k];        //多出来的(需要删除的部分)
                    dp[i]=min(dp[i],dp[j]+dele);                                                        //更新状况<span id="transmark"></span>
                }
            }
        }
        printf("%d\n",dp[L-1]);
    }
    return 0;
}

你可能感兴趣的:(POJ 3267 The Cow Lexicon DP 字符串匹配问题扩展)