洛谷P2432 zxbsmk爱查错

题目

DP,需要注意边界上的问题。

状态定义\(dp[i]\)为句子第i位去除字母的最小值,答案就是\(dp[len]\)

易得状态转移方程为:

\[dp[i]=min(dp[i-1]+1,dp[l]+(i-l-len[j]))\]l是保留第j个字符串的右端点,len[j]是第j个字符串的长度。

#include <bits/stdc++.h>
using namespace std;
int w, le, len[1001], dp[1001];
char juzi[1001];
char word[1001][1001];
int has (string s)
{
    int len = s.size();
    int ans = 0;
    for (int i = 0; i < len; i++)
    {
        ans = (ans * 451481 + (s[i] - '0')) % 19260817;
    }
    return ans;
}
int main()
{
    scanf("%d%d", &w, &le);
    for (int i = 0; i < le; i++)
        cin >> juzi[i];
    for (int i = 1; i <= w; i++)
    {
        cin >> word[i];
        len[i] = strlen(word[i]);
    }
    memset(dp, 0x3f, sizeof(dp)); //dp[i]表示的是
    dp[0] = 1;
    for (int i = 1; i < le; i++)
    {
        dp[i] = dp[i - 1] + 1;
        for (int j = 1; j <= w; j++)
        {
            int l = i, r = len[j] - 1;//需要等到lenj
            while (l >= 0 && r >= 0)
            {
                if (word[j][r] == juzi[l]) r--, l--;
                else l--;
            }
            if (r < 0)//说明此单词全部被选走了。
                dp[i] = min(dp[i], dp[l] + (i - l - len[j])); 
        }
    }
    printf("%d", dp[le - 1]);
}
/*
6 10
browndcodw 
cow 
milk
white
black
brown
farmer
2   
*/

猜你喜欢

转载自www.cnblogs.com/liuwenyao/p/11709097.html