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]
翰林课程体验,退费流程快速投诉邮箱: yuxi@linstitute.net 沪ICP备2023009024号-1