poj 3267(dp水题)

Description

Few know that the cows have their own dictionary with W (1 ≤ W ≤ 600) words, each containing no more 25 of the characters 'a'..'z'. Their cowmunication system, based on mooing, is not very accurate; sometimes they hear words that do not make any sense. For instance, Bessie once received a message that said "browndcodw". As it turns out, the intended message was "browncow" and the two letter "d"s were noise from other parts of the barnyard.

The cows want you to help them decipher a received message (also containing only characters in the range 'a'..'z') of length L (2 ≤ L ≤ 300) characters that is a bit garbled. In particular, they know that the message has some extra letters, and they want you to determine the smallest number of letters that must be removed to make the message a sequence of words from the dictionary.

Input

Line 1: Two space-separated integers, respectively: W and L 
Line 2: L characters (followed by a newline, of course): the received message 
Lines 3..W+2: The cows' dictionary, one word per line

Output

Line 1: a single integer that is the smallest number of characters that need to be removed to make the message a sequence of dictionary words.

Sample Input

6 10
browndcodw
cow
milk
white
black
brown
farmer

Sample Output

2

思路:

        主要是在每一段区间内,在期间长度大于单词长度的情况下,对单词进行判断,这个区间内还需要删掉多少个单词,并做记录,状态转移方程为:dp[i] = min(d[j]+区间(i,j)内最少删除单词的个数).

 

一种比较直白的思路,不过会超时.

#include<stdio.h>
#include<string.h>
char word[500][30];
char a[400];
int sum[500];

int pipei(int l,int r,char *p)
{
    int len = strlen(p);
    int j = 0;
    for(int i = l; i <= r && r-i+1 >= j; i++)
    {
        if(a[i] == p[j])
            j++;
    }
  //  printf("%d\n",r-l-j);
    return r-l-j+1;
}

int main(){
    for(int i = 0; i < 400; i++){
        sum[i] = 500;
    }
    sum[0] = 1;
    int n,m;
    scanf("%d%d",&n,&m);
    scanf("%s",a);
    for(int i = 0; i < n; i++)
        scanf("%s",word[i]);
    for(int i = 0; i < m; i++){
        sum[i] = i+1;
        int min1 = 500;
        for(int j = 0; j < i; j++){
                for(int k =0; k < n; k++){
                        if(j-i+1 < strlen(word[i]))
                            continue;
                       int x  = sum[j] + pipei(j,i,word[k]);
                       if(x < min1)
                        min1  = x;
                }
                if(sum[i] > min1)
                    sum[i] = min1;
        }
    }
    printf("%d\n",sum[n-1]);
    return 0;

}

这种方法的话思路看起来比较直白,不过在匹配上要花时间确定左区间,所以时间上话费了一些时间(并不能AC),在优化后,不需要先确定左区间,从右区间遍历, 这个时间复杂度上相对来说优化了很多,而且能AC

 

  1. #include <iostream>

  2. #include <stdio.h>

  3. #include <algorithm>

  4. #include <stdlib.h>

  5. #include <math.h>

  6. #include <string.h>

  7. #include <vector>

  8. #include <queue>

  9. #include <stack>

  10. #include <map>

  11. #include <set>

  12. using namespace std;

  13. int w,l;

  14. int dp[2333];

  15. char key[2333];

  16. char dic[2333][233];

  17. int min(int a,int b)

  18. {

  19. if(a<b) return a;

  20. else return b;

  21. }

  22. int main()

  23. {

  24. cin>>w>>l;

  25. scanf("%s",key);

  26. for(int i=1;i<=w;i++)

  27. {

  28. scanf("%s",dic[i]);

  29. }

  30. dp[0]=1;

  31. for(int i=1;i<l;i++)

  32. {

  33. dp[i]=dp[i-1]+1;

  34. int len;int k;

  35. for(int j=1;j<=w;j++)

  36. {

  37. len=strlen(dic[j])-1;

  38. k=i;

  39. if(len>i) continue;

  40. while(len>=0&&k>=0&&k>=len)

  41. {

  42. if(key[k]==dic[j][len]) len--;

  43. k--;

  44. }

  45. if(len<0) dp[i]=min(dp[i],dp[k]+i-k-strlen(dic[j]));

  46. }

  47. }

  48. cout<<dp[l-1];

  49. return 0;

  50. }

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值