https://codeforces.com/contest/2005/problem/C
题意:n个长度为m的字符串,可以任意选取若干个字符串组合起来,然后从中选择narek5个字符拼凑字符串,拼凑成功加5分,如果字母是narek中的其中一个并且没有使用,则扣一分,求最大分数。
思路:dp,维护一个长度为5的数组,依次考虑在当前字符串中以第i个字母为起始字母时,能得到的最大分值。
总结:这里是如何在dp的过程中,保持之前的信息的呢?第一个匹配的字符一定是n,那么dp[0] = 0,后面匹配到了第几个字符,就让第几个字符的下一个代价为0,这样在下一个串中可以接着这个字符进行匹配,当匹配到结尾的时候,在下个串中可以获得的代价就可以+5。
inline void solve(){
int n, m;
cin >> n >> m;
vector<string> a(n);
for (auto& x : a) {
cin >> x;
}
array<int, 5> dp;
dp.fill(-INF);
dp[0] = 0;
const string target = "narek";
for (const auto& s : a) {
auto cur_dp = dp;
for (int i = 0; i < 5; ++i) {
int j = i;
int res = dp[i];
for (const auto& c : s) {
if (c == target[j]) {
j ++;
if (j == 5) {
res += 5;
j = 0;
}
}
else if (target.find(c) != target.npos) {
res --;
}
}
cur_dp[j] = max(cur_dp[j], res);
}
dp = cur_dp;
}
int ans = 0;
for (int i = 0; i < 5; ++i) {
ans = max(ans, dp[i] - i);
}
cout << ans << '\n';
}
标签:Lazy,cur,int,res,auto,Narek,dp,target
From: https://www.cnblogs.com/yxcblogs/p/18419903