【POJ 3267】 The Cow Lexicon

【POJ 3267】 The Cow Lexicon

训练计划里把这题排到了topo里。。。。然后我就这么死盯研究了一周topo算法(期间经历了三个人生风波。。。。大物考试 高数考试跟模电考试…………)啥不说了……上dp代码…………没错 这是个dp!。。。赤果果的dp。。就呢么傻呆呆地研究Topo算法……结果没研究出来。。
题意是给一个字符串和m个单词组成的字典,问最少删除几个字母能让这个字符串变成由字典中几个单词首位链接组成的字符串
dp思路还算好想 逆推 dp数组的下标是遍历字符串的起点 然后从尾部截取字符串 遍历找所需最少删除字母数,。每次把所有字典单词遍历一遍 找到用该单词所需最多字母删除数接着不断dp。。。。讲的有点糟糕 看代码吧

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>

using namespace std;

char str[301],ch[600][26];
int dp[301],len[600];

int main()
{
    int w,l,i,j,cnt,p;
    scanf("%d%d",&w,&l);
    scanf("%s",str);
    for(i = 0; i < w; ++i)
    {
        scanf("%s",ch[i]);
        len[i] = strlen(ch[i]);
    }

    dp[l-1] = 0;

    for(i = l-1; i >= 0; --i)
    {
        dp[i] = dp[i+1]+1;
        for(j = 0; j < w; ++j)
        {
            if(len[j] > l-i || str[i] != ch[j][0]) continue;
            cnt = 0;
            p = i;
            while(p < l)
            {
                if(ch[j][cnt] == str[p++])
                    cnt++;
                if(cnt == len[j])
                {
                    dp[i] = min(dp[i],dp[p]+p-i-len[j]);
                    break;
                }
            }
        }
    }
    printf("%d\n",dp[0]);
    return 0;
}

你可能感兴趣的:(dp)