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';
}