Processing math: 100%
(Analysis by Danny Mittal)

Let s be the given string, and c be the given list of deletion costs.

Subtask N2000

We will use DP. Let dp(k,x,j) be the minimum cost to delete characters in s[1k] so that we have x occurrences of "bessie" as well as having the first j characters of "bessie" at the very end (without any characters after). The answer will be x and dp(|s|,x,0) for the largest x such that the latter is finite.

There are two general transitions. The first is to transition from dp(k1,x,j) to dp(k,x,j) by deleting sk, adding ck cost. The second occurs when sk is in a "bessie", in which case for all j such that sk is the jth letter in "bessie" (with j being 1-indexed), we can go from dp(k1,x,j1) to dp(k,x,j) without adding any cost. Thus, we can compute the DP using the following equations. If sk is the jth character in "bessie",

dp(k,x,j)=min(dp(k1,x,j)+ck,dp(k1,x,j1)).
Otherwise,
dp(k,x,j)=dp(k1,x,j)+ck.
Each of these transitions has a special case associated with j=0. For the first one, because 'the first 0 characters of "bessie" occurring at the end of the string' isn't actually a real constraint, we don't need to delete the added character to maintain it, so we can transition directly from dp(k1,x,0) to dp(k,x,0) without any added cost. For the second one we need to account for having a whole "bessie" at the end of the string that we would like to include in the count x. We can do this cleanly by transitioning from dp(k,x1,6) to dp(k,x,0). Thus, we can write
dp(k,x,0)=min(dp(k1,x,0),dp(k,x1,6)).
We therefore have a DP with O(|s|2) states (because the amount of "bessie"s in s is at most |s|6) with constant time transitions, giving an O(|s|2) algorithm.

No additional constraints

We can optimize the above DP by moving x from the state to the value. The idea here is that because we want to maximize the number of "bessie"s first and minimize the cost second, a configuration that achieves x "bessie"s with y cost is always better than a configuration that achieves x<x "bessie"s and y cost regardless of if y is much smaller than y.

We can therefore define dp(k,j) to be the optimal pair (x,y) for deleting characters in s[1k] to end up with the first j characters of "bessie" at the end, where x is the number of additional "bessie"s in that string and y is the cost. Optimality is then determined first by higher x then by lower y.

The above transitions can be written as follows, with addition of pairs defined as (a,b)+(c,d)=(a+c,b+d).

If sk is the jth character in "bessie",

dp(k,j)=opt(dp(k1,j)+(0,ck),dp(k1,j1)).
Otherwise,
dp(k,j)=dp(k1,j)+(0,ck).
And,
dp(k,0)=opt(dp(k1,0),dp(k,6)+(1,0)).
The number of states has been reduced to O(|s|) while the transitions are still constant time, giving a O(|s|) solution.

Python code that closely follows the analysis:

s = input()
c = list(map(int, input().split()))
BESSIE = "bessie"
INF = 300_000_000

def opt(a, b):
    if a[0] > b[0]:
        return a
    if b[0] > a[0]:
        return b
    if a[1] < b[1]:
        return a
    return b

def add(a, b):
    return (a[0] + b[0], a[1] + b[1])

dp = [[(-1, INF)] * 7 for _ in range(len(s) + 1)]
dp[0][0] = (0, 0)

for k in range(1, len(s) + 1):
    for j in range(1, 7):
        if s[k - 1] == BESSIE[j - 1]:
            dp[k][j] = opt(add(dp[k - 1][j], (0, c[k - 1])), dp[k - 1][j - 1])
        else:
            dp[k][j] = add(dp[k - 1][j], (0, c[k - 1]))
    dp[k][0] = opt(dp[k - 1][0], add(dp[k][6], (1, 0)))

bessies, cost = dp[len(s)][0]
print(bessies)
print(cost)

Ben's code:

s = input()
costs = map(int, input().split())

target = "bessie"
dp = [(float("-inf"), 0) for _ in target]
dp[0] = (0, 0)

for c, cost in zip(s, costs):
    ndp = [(float("-inf"), 0) for _ in target]
    for i in range(len(target)):
        ndp[i] = max(ndp[i], (dp[i][0], dp[i][1] - (i > 0) * cost))
        if target[i] == c:
            j = (i + 1) % len(target)
            ndp[j] = max(ndp[j], (dp[i][0] + 1, dp[i][1]))
    dp = ndp

oc, minus_cost = max([(progress // len(target), cost) for progress, cost in dp])
print(oc)
print(-minus_cost)

#include <bits/stdc++.h>
using namespace std;
 
int main() {
    string s;
    cin >> s;
 
    vector<int> costs;
    int cost;
    for (int i = 0; i < s.size(); i++) {
        cin >> cost;
        costs.push_back(cost);
    }
 
    string target = "bessie";
    vector<pair<int, int>> dp(target.size(), {-1e9, 0});
    dp[0] = {0, 0};
 
    for (int i = 0; i < s.size(); i++) {
        vector<pair<int, int>> ndp(target.size(), {-1e9, 0});
        char c = s[i];
        for (int j = 0; j < target.size(); j++) {
            ndp[j] =
                max(ndp[j], {dp[j].first, dp[j].second - (j > 0) * costs[i]});
            if (target[j] == s[i]) {
                int k = (j + 1) % target.size();
                ndp[k] = max(ndp[k], {dp[j].first + 1, dp[j].second});
            }
        }
        swap(dp, ndp);
    }
 
    pair<int, int> mx{-1e9, 0};
    for (int i = 0; i < target.size(); i++)
        mx = max(mx, {dp[i].first / target.size(), dp[i].second});
 
    cout << mx.first << endl;
    cout << -mx.second << endl;
 
    return 0;
}