poj 3267 the cow lexicon

戳这里原题

大致题意:给你w个单词和长度为l的字符串,问在字符串中删除多少个字符可以使其匹配到单词序列

嗯然后是dp。

开dp[i]记录在第i位及之前要删除多少字符,已知找到dp[i],初始状态dp【l】=0,然后从后往前扫输入的字符串。这个时候,dp方程有两种

dp【i】=dp【i+1】+1;(不能匹配)

dp【i】=min(dp【i】,dp[pm]+(pm-i)+len);

第一个方程不难理解,主要是第二个;
1. pm是对于输入字符串的指针,i是当前这个单词的首字母的位置,p每个单词的pm指的就是字符串中和单词最后一个字母相等的位置。(pm-i)就是这中间一共有多少个字符,(pm-i)+len就是这一段字母中需要删减多少字母
2. 关于怎么匹配,直接上代码喽!

cpp
#include<iostream> 
#include<cstdio> 
#include<cstring> 

using namespace std;  
char str[1000];  
char word[1000][30];  
int dp[1000];

int main()
{  
    int w,l,i,j,pos,k,temp;  
    scanf("%d%d",&w,&l); 
    scanf("%s",str);  
    for(i=0;i<w;i++)
    {  
        scanf("%s",word[i]);  
    }
    dp[l]=0;    
    for(i=l-1;i>=0;i--)
    {  
        dp[i]=dp[i+1]+1;  
        for(j=0;j<w;j++) 
        {  
            int len=strlen(word[j]); 
            if(len<=l-i && word[j][0]==str[i])  
            {
                int pm=i;  
                int pw=0;  
                while(pm<l) 
                {  
                    if(word[j][pw]==str[pm++])  
                       pw++;  
                    if(pw == len)  
                   {       
                     dp[i]=min(dp[i],dp[pm]+(pm-i)-len); 
                     break;                            
                   }                                     
                }  
            }  
        }  
    }
    printf("%d\n",dp[0]);    
    return 0;  
}  

你可能感兴趣的:(poj3267)