Bessie has been playing the popular fighting game Moortal Cowmbat for a long time now. However, the game developers have recently rolled out an update that is forcing Bessie to change her play style.
The game uses?MM?buttons labeled by the first?MM?lowercase letters (1≤M≤261≤M≤26). Bessie's favorite combo of moves in the game is a length-NN?string?SS?of button presses (1≤N≤1051≤N≤105). However, due to the most recent update, every combo must now be made from a series of "streaks", where a streak is defined as a series of the same button pressed at least?KK?times in a row (1≤K≤N1≤K≤N). Bessie wants to modify her favorite combo to produce a new combo of the same length?NN, but made from streaks of button presses to satisfy the change in rules.
It takes?aijaij?days for Bessie to train herself to press button?jj?instead of button?ii?at any specific location in her combo (i.e. it costs?aijaij?to change a single specific letter in?SS?from?ii?to?jj). Note that it might take less time to switch from using button?ii?to an intermediate button?kk?and then from button?kk?to button?jj?rather than from?ii?to?jj?directly (or more generally, there may be a path of changes starting with?ii?and ending with?jj?that gives the best overall cost for switching from button?ii?ultimately to button?jj).
Help Bessie determine the smallest possible number of days she needs to create a combo that supports the new requirements.
The first line of input contains?NN,?MM, and?KK. The second line contains?SS, and the final?MM?lines contain an?M×MM×M?matrix of values?aijaij, where?aijaij?is an integer in the range?0…10000…1000?and?aii=0aii=0?for all?ii.
Output a single number, representing the minimum number of days Bessie needs to change her combo into one that satisfies the new requirements.
5 5 2 abcde 0 1 4 4 4 2 0 4 4 4 6 5 0 3 2 5 5 5 0 4 3 7 0 5 0
5
The optimal solution in this example is to change the a into b, change the d into e, and then change both e’s into c’s. This will take?1+4+0+0=51+4+0+0=5?days, and the final combo string will be bbccc.
Problem credits: Eric Wei
<h3>USACO 2019 December Contest, Gold Problem 3. Moortal Cowmbat 题解(翰林国际教育提供,仅供参考)</h3>
<p style="text-align: center;">题解请<a href="/register" target="_blank" rel="noopener">注册</a>或<a href="/login" target="_blank" rel="noopener">登录</a>查看</p>
[/hide]
(Analysis by Eric Wei)
First, note that it is sometimes possible to change a letter to a different one in faster time than what is originally given. To deal with this, we run Floyd-Warshall on the letters to determine the actual shortest amount of time to change each letter to any other letter.
We can now store the fastest time the letter in each index?ii?can be changed to a different letter?jj, which we represent in a cost matrix,?cst[i][j]cst[i][j]. After this, we can now utilize prefix sums to speed up future computation. We store this in?ps[i][j]ps[i][j], representing the sum of all?cst[k][j]cst[k][j]?for?k≤ik≤i.
Finally, we can use DP. Let?dp[i][j]dp[i][j]?represent the smallest amount of time needed so that the first?ii?letters create a “valid combo” and the last letter is?jj?(so the last?KK?letters are all?jj). We also create an array,?dpmin[i]dpmin[i], which represents the minimum value of all?dp[i][j]dp[i][j]?across all possible?jj. The transition is as follows:
dp[i][j] = min(ps[i][j]-ps[i-K][j]+dpmin[i-K],dp[i-1][j]+cst[i][j]);
There are two possibilities we must consider: either the rightmost streak is exactly?KK?letters long, or it is more than that, corresponding to these two possibilities. Calculating?dpmindpmin?is easy from this, and the final answer is simply?dpmin[N]dpmin[N]. The runtime is?O(M3+N?M)O(M3+N?M). My code follows:
#include <bits/stdc++.h> using namespace std; #define FOR(i, a, b) for (int i=(a); i<=(signed)(b); i++) #define F0R(i, a) for (int i=0; i<(signed)(a); i++) #define MN 100005 #define MA 26 int n, m, k; string s; int d[MA][MA]; int cst[MN][MA]; int ps[MN][MA]; int dp[MN][MA]; int mn[MN]; int main(){ ios_base::sync_with_stdio(false); cin.tie(NULL); freopen("cowmbat.in", "r", stdin); freopen("cowmbat.out", "w", stdout); cin >> n >> m >> k >> s; F0R(i, m) F0R(j, m) cin >> d[i][j]; F0R(c, m) F0R(a, m) F0R(b, m) d[a][b] = min(d[a][b], d[a][c]+d[c][b]); FOR(i, 1, n){ F0R(j, m){ cst[i][j] = d[s[i-1]-'a'][j]; ps[i][j] = ps[i-1][j]+cst[i][j]; //cout << i << " " << j << " " << cst[i][j] << "\n"; } } memset(dp, 0x3f, sizeof dp); memset(mn, 0x3f, sizeof mn); mn[0] = 0; FOR(i, 1, n){ F0R(j, m){ dp[i][j] = min(dp[i][j], dp[i-1][j]+cst[i][j]); if (i >= k) dp[i][j] = min(dp[i][j], ps[i][j]-ps[i-k][j]+mn[i-k]); //cout << "dp " << i << " " << j << " " << dp[i][j] << "\n"; mn[i] = min(mn[i], dp[i][j]); } } cout << mn[n] << "\n"; }
[/hide]
? 2025. All Rights Reserved. 沪ICP备2023009024号-1