leetcode 1547. 切棍子的最小成本

有一根长度为 n 个单位的木棍,棍上从 0 到 n 标记了若干位置。例如,长度为 6 的棍子可以标记如下:

给你一个整数数组 cuts ,其中 cuts[i] 表示你需要将棍子切开的位置。

你可以按顺序完成切割,也可以根据需要更改切割的顺序。

每次切割的成本都是当前要切割的棍子的长度,切棍子的总成本是历次切割成本的总和。对棍子进行切割将会把一根木棍分成两根较小的木棍(这两根木棍的长度和就是切割前木棍的长度)。请参阅第一个示例以获得更直观的解释。

返回切棍子的 最小总成本 。

解题思路:

①定义一个int型m变量来存储切棍子的次数,并将cuts数组按升序排序 。

int m = cuts.size(); // 要切割的次数
sort(cuts.begin(), cuts.end());

②进行任意一次切割时,待切木棍的左端要么是初始位置0,要么是之前某一次切割的位置;待切木棍的右端要么是末端位置n,要么是之前某一次切割的位置。因此在cuts数组头加上0以及末尾加上n。以便计算成本。

cuts.insert(cuts.begin(), 0); // 在cuts数组头部加0
cuts.push_back(n); // 在cuts数组尾部添加n
// 创建有个(m+2)*(m+2)的二维数组f[i][j],该数组表示切割最小成本
vector<vector<int>> f(m+2, vector<int>(m+2)); 

 ③用f[i][j]表示在当前待切割的木棍的左端点为 cuts[i−1],右端点为 cuts[j+1] 时,将木棍全部切开的最小总成本。

④为了得到最小总成本,定义一个int型k表示枚举第一刀的位置。如果第一刀的位置为 cuts[k],其中 k∈[i,j],那么我们会将待切割的木棍分成两部分,左侧部分的木棍为 cuts[i−1..k],对应的可以继续切割的位置为 cuts[i..k−1];右侧部分的木棍为 cuts[k..j+1],对应的可以继续切割的位置为cuts[k+1..j]。

 // 从待切木棍最后一个点开始
 for (int i = m; i >= 1; i--) {
     for (int j = i; j <= m; j++) {
     // 若i==j,则表示只要切一个点,成本只有待切木棍的长度;若不是,则先置f[i][j]为无穷大
           f[i][j] = (i == j ? 0 : INT_MAX);
           // 分析在待切木棍上的各个待切点,取成本最小
           for (int k = i; k <= j; k++) {
               f[i][j] = min(f[i][j], f[i][k-1] + f[k+1][j]);
           }
           f[i][j] += cuts[j+1] - cuts[i-1];
     }
}

⑤每次切的成本都是cuts[j+1]−cuts[i−1]。

f[i][j] += cuts[j+1] - cuts[i-1];

⑥最后返回从f[1][m]。

return f[1][m];

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值