有一根長度為n的木棍,從0到n標記了若干個位置。給定一個陣列cuts[m],表示要在cuts[i]位置切開,每次切割的成本是當前木棍的長度,求總成本的最小值。
2<=n<=1e6; 1<=m<=min(n-1,100); 1<=cuts[i]<=n-1; cuts[i]各不相同
正向思考的話可以記憶化dfs,也可以逆向思考,轉成合並問題,用區間dp求解。這裡用的是記憶化dfs。
class Solution {
public:
int dp[105][105];
int minCost(int n, vector<int>& cuts) {
int m = cuts.size();
sort(cuts.begin(), cuts.end());
memset(dp, -1, sizeof(dp));
auto sum = [&](int L, int R) -> int {
int x = 0, y = n;
if (L != 0) x = cuts[L-1];
if (R != m-1) y = cuts[R+1];
return y-x;
};
auto dfs = [&](auto self, int L, int R) -> int {
if (L > R) return 0;
if (dp[L][R] != -1) return dp[L][R];
int ans = 1e9;
for (int i = L; i <= R; i++) {
ans = min(ans, self(self,L,i-1) + self(self,i+1,R));
}
ans += sum(L,R);
return dp[L][R] = ans;
};
return dfs(dfs, 0, m-1);
}
};