POJ 3267 The Cow Lexicon

题目链接:http://poj.org/problem?id=3267

题目:给出一个字典和一个字符串,问这个字符串中最少删去几个字符,能使它变成由字典中的单词组成的序列。

分析:从字符串的第一个字符开始,在字典中依次寻找与其匹配的单词:

dp[i] = min( dp[i], dp[ i - 1] + 1 );                          如果找不到匹配单词

dp[i] = min( dp[i], dp[ i - ( len[j] + cnt ) ] + cnt );    如果第 j 个单词与其匹配

dp[i] 代表到字符串第 i 个字母时需要删去多少个字符,len[j]是字典中第 j 个单词的长度,cnt 是如果字符串与该单词匹配需要删去的字母数目。

字典中可能有不止一个单词与字符串匹配,应当选择删去字母数最小的那个。

 1 #include <cstdio>
 2 #include <cstring>
 3 
 4 const int INF = 2147483647;
 5 
 6 int dp[310];
 7 int len[610];
 8 char dictionary[610][30];
 9 char str[310];
10 int W, L;
11 
12 int min( int a, int b )
13 {
14     return a < b ? a : b;
15 }
16 
17 int DP()
18 {
19     for ( int i = 1; i <= L; i++ )
20        dp[i] = INF;
21 
22     dp[0] = 0;
23 
24     for ( int i = 1; i <= L; i++ )
25     {
26         for ( int j = 0; j < W; j++ )
27         {
28             int cnt = 0;                  //匹配当前单词需要删去的字母个数
29             int dic_i = len[j] - 1;
30             int str_i = i - 1;
31 
32             while ( str_i > -1 && dic_i > -1 )    //从后往前匹配
33             {
34                 if ( str[str_i] == dictionary[j][dic_i] )
35                 {
36                     --str_i;
37                     --dic_i;
38                 }
39                 else
40                 {
41                     --str_i;
42                     ++cnt;
43                 }
44             }
45 
46             if ( dic_i < 0 )         //如果匹配成功
47                  dp[i] = min( dp[i], dp[ i - ( len[j] + cnt ) ] + cnt );
48             else dp[i] = min( dp[i], dp[i - 1] + 1 );   //如果匹配失败
49         }
50     }
51 
52     return dp[L];
53 }
54 
55 int main()
56 {
57     while ( scanf( "%d%d", &W, &L ) != EOF )
58     {
59         scanf( "%s", str );
60         for ( int i = 0; i < W; i++ )
61         {
62             scanf( "%s", dictionary[i] );
63             len[i] = strlen( dictionary[i] );
64         }
65 
66         printf( "%d\n", DP() );
67     }
68     return 0;
69 }
原文地址:https://www.cnblogs.com/GBRgbr/p/2615815.html