創作長度為 n 的歌曲,每位置選擇 m 種音符之一。連續兩音符 (a,b) 產生美感分 score(a,b)。部分位置固定音符(正數),其餘可任意選(-1)。最大化總美感。n ≤ 100, m ≤ 50, T ≤ 10。
dp[i][j] 表示前 i 個位置,第 i 位選音符 j 的最大美感。dp[i][j] = max_k { dp[i-1][k] + score(k, j) },受固定音符約束。dp[1][j] = 0(無前驅)。根據第 i、i-1 位是否固定,分四種情況轉移,避免無效循環:
dp[i][fixed]。dp[i][j]。for (int i = 2; i <= n; i++) {
if (b[i] != -1) { // 當前固定
if (b[i-1] == -1) {
for (int j = 1; j <= m; j++)
dp[i][b[i]] = max(dp[i][b[i]], dp[i-1][j] + a[j][b[i]]);
} else
dp[i][b[i]] = dp[i-1][b[i-1]] + a[b[i-1]][b[i]];
} else { // 當前不固定
if (b[i-1] == -1) {
for (int j = 1; j <= m; j++)
for (int k = 1; k <= m; k++)
dp[i][j] = max(dp[i][j], dp[i-1][k] + a[k][j]);
} else {
for (int j = 1; j <= m; j++)
dp[i][j] = max(dp[i][j], dp[i-1][b[i-1]] + a[b[i-1]][j]);
}
}
}
本題是典型的線性 DP,狀態定義清晰,轉移方程直觀。關鍵在於仔細處理固定/自由位置的條件分支,代碼雖長但邏輯清晰,屬於「水 DP」範疇,適合鍛鍊 DP 建模與分支處理能力。