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预处理。
给出一个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; }