AOJ-399 Longest Prefix

题目大意:
给出一个list,由最多200个单词组成,每个单词最多10个字母。再给出一串字符串,问你刚刚给出的list能构成的最大前缀是多长。
解题思路:
动态规划
dp[i]表示到第i个字符能否被匹配
那么其状态转移可以表示为:
dp[i] = dp[i - len] ? 1 : 0;
其中len为list里面的各个单词的长度,且需要匹配。
这题题目给出的是20w的长度如果这样来看暴力搞的话复杂度为2 * 10 ^5 * 200 * 10 = 4 * 10^8
这道题目看样子数据是给小了。如果严格按照这个数据要求的话,应该需要用kmp预处理。

代码:

#include <string>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn = 2e5 + 10;

string str, tmp;
char ch[210][15];
int dp[maxn], a[210];

int main(){
    str.clear(); tmp.clear();
    int len , cnt = 0, flag, tol;
    while(cin >> ch[cnt] && ch[cnt][0] != '.') {a[cnt] = strlen(ch[cnt]); ++cnt;}
    while(cin >> tmp) str += tmp;
    dp[0] = 1;
    len = str.length();
    for(int i = 0; i < len; ++i){
        for(int j = 0; j < cnt; ++j){
            tol = a[j]; flag = 1;
            if(i + tol <= len){
                for(int k = 0; k < tol; ++k){
                    if(str[i+k] == ch[j][k]) continue;
                    flag = 0;
                }
                if(flag && dp[i]) dp[i + tol] = 1;
            }
        }
    }

    for(int i = len; i >= 0; --i){
        if(dp[i] == 1) { cout << i << endl; break;}
    }
    return 0;
}


原文地址:https://www.cnblogs.com/wiklvrain/p/8179412.html