链接:https://codeforces.com/contest/1107/problem/E
大意:给一个100长度的01串s,规定字符相同的子串可以消掉,消掉长度为i的子串得分pi,求最多能得多少分,
解法:
dp[st][en][suc]代表[st,en]的子串从前面借到了suc个跟s[st]一样字符,这一段可以得到多少分
对于s[st]这个从前面继承到的字符可以从这里断掉,得到p[suc+1]+dp[st+1][en][0]
也可以把自己的这个字符继续继承下去,把自己和自己的前辈交给下一个跟s[st]相同的点j,得到
dp[j][en][suc+1]+dp[i+1][j-1][0]
核心代码:
const int maxn = int(110);
int n; string s;
int a[maxn];
ll dp[maxn][maxn][maxn];
ll solve(int st, int en, int suc = 0)
{
ll &ret = dp[st][en][suc];
if(ret != -1)return ret;
if (st == en + 1)return 0;
else if (st > en)ret = -inf * 1LL * inf;
else if (en == st)return a[suc + 1];
else
{
ret = a[suc + 1] + solve(st + 1, en);
for (int i = st + 1; i <= en; ++i)
{
if (s[st] == s[i])
{
ret = max(ret, solve(i, en, suc + 1) + solve(st + 1, i - 1));
}
}
}
return ret;
}
memset(dp, -1, sizeof(dp));
cin >> n >> s; s = ' ' + s + ' ';
RE2(i, n)cin >> a[i];
cout << solve(1, n) << endl;