题目大意
你有两个 CPU,n 个程序要运行,总共 k 种程序需要运行。在不同条件下程序运行的时间不同,但连续运行的时间满足小于等于在不连续状态下运行的时间。
简要分析
很容易想到 dp。
最容易想到的状态是 dp_{i,j,k} 表示当前处理到第 i 个程序,CPU1 执行的最后一个程序种类为 j,CPU2 执行的最后一个程序种类为 k。
显然复杂度炸了。
不难发现,一定会有一个 CPU 执行的最后一个程序的种类为 a_{i-1},于是可以优化掉一维。
转移按照定义转移即可。
代码实现
#include <cstdio> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; const ll maxn = 5e3 + 7; const ll INF = 1e9 + 7, MOD = 998244353; inline ll read() { char cCc; ll xXx = 0, wWw = 1; while (cCc < '0' || cCc > '9') (cCc == '-') && (wWw = -wWw), cCc = getchar(); while (cCc >= '0' && cCc <= '9') xXx = (xXx << 1) + (xXx << 3) + (cCc ^ '0'), cCc = getchar(); xXx *= wWw; return xXx; } inline void write(ll xXx) { if (xXx < 0) putchar('-'), xXx = -xXx; if (xXx > 9) write(xXx / 10); putchar(xXx % 10 + '0'); } ll A[maxn], cold[maxn], hot[maxn], dp[maxn][maxn]; void solve() { ll n = read(), k = read(); for (ll i = 1; i <= n; i++)A[i] = read(); for (ll i = 1; i <= k; i++)cold[i] = read(); for (ll i = 1; i <= k; i++)hot[i] = read(); A[0] = -1; for (ll i = 0; i <= n; i++) for (ll j = 0; j <= k; j++) dp[i][j] = 1e18; dp[1][0] = cold[A[1]]; for (ll i = 2; i <= n; i++) { ll first = A[i - 1]; for (ll j = 0; j <= k; j++) { dp[i][j] = min(dp[i][j], dp[i - 1][j] + (A[i] == first ? hot[A[i]] : cold[A[i]])); dp[i][first] = min(dp[i][first], dp[i - 1][j] + (A[i] == j ? hot[A[i]] : cold[A[i]])); } } ll ans = 1e18; for (ll i = 0; i <= k; i++) ans = min(ans, dp[n][i]); cout << ans << '\n'; } signed main() { // freopen("code.in","r",stdin); // freopen("code.out","w",stdout); ll T = read(); while (T--)solve(); return 0; }
——\mathscr{ClaudeZ.}