2025-11-11:木材运输的最小成本。用go语言,给定两根木料,长度分别为 n 和 m。要用三辆卡车运走它们,每辆车只能装一段木头,且所装木段的长度不能超过 k。你可以把一根木头切成若干更短的段;每次把长度为 x 的段分成 len1 和 len2 时需付出代价 len1 * len2(且 len1 + len2 = x),可以进行多次切割以得到更多段。求在满足每辆车最多装一段且每段长度 ≤ k 的前提下,使两根木料都能被装运的最低总切割费用;若不需要切割则费用为 0。
2 <= k <= 100000。
1 <= n, m <= 2 * k。
输入数据保证木材总存在能被运输的方案。
输入: n = 6, m = 5, k = 5。
输出: 5。
解释:
将长度为 6 的木材切割成长度为 1 和 5 的两段,成本为 1 * 5 == 5。现在三段长度分别为 1、5 和 5 的木材可以分别装载到每辆卡车。
题目来自力扣3560。
过程分步骤描述
-
问题分析:
- 目标是用三辆卡车运走两根木料,每辆车装载一段木料,且每段长度不超过
k。 - 如果木料长度本身不超过
k,可以直接装载(无需切割);否则需要切割。每次切割将一段长度为x的木料分为len1和len2(len1 + len2 = x),代价为len1 * len2。 - 关键约束:总段数不能超过三(因为只有三辆车)。因此:
- 如果两根木料长度都小于等于
k,不需要切割(总段数为二),成本为0。 - 如果一根木料长度大于
k,另一根小于等于k,则只需切割长木料一次(总段数变为三),成本为切割长木料的代价。 - 如果两根木料长度都大于
k,则至少需要切割两次(总段数至少为四),但车辆不足,无法运输。不过题目保证输入数据总是有解,因此这种情况不会出现(输入约束n, m ≤ 2*k且至少一根木料长度 ≤k)。
- 如果两根木料长度都小于等于
- 目标是用三辆卡车运走两根木料,每辆车装载一段木料,且每段长度不超过
-
代码逻辑:
- 计算两根木料中的最大长度
maxLen = max(n, m)。 - 如果
maxLen ≤ k,说明两根木料均无需切割,直接返回成本0。 - 如果
maxLen > k,则必须切割长木料。最小切割代价发生在将长木料一端切下尽可能小的一段(以满足每段 ≤k):- 切割后,一段长度为
k,另一段长度为maxLen - k,代价为k * (maxLen - k)。 - 例如,
n = 6,m = 5,k = 5时,切割长木料(长度6)为1和5,代价1 * 5 = 5。
- 切割后,一段长度为
- 代码通过
k * (max(n, m) - k)计算该代价,并与0取最大值(避免负值)。
- 计算两根木料中的最大长度
-
为什么忽略短木料?
- 当
max(n, m) > k时,题目保证另一根木料长度min(n, m) ≤ k(否则无解)。因此短木料无需切割,直接装载即可。 - 代码仅处理长木料,因为它是唯一需要切割的木料,且切割一次后总段数恰好为三(长木料变两段,短木料一段)。
- 当
-
时间复杂度:
- 代码仅涉及比较和算术操作(如取最大值、乘法),所有操作在常数时间内完成。
- 总的时间复杂度为 O(1)。
-
空间复杂度:
- 代码只使用了固定数量的变量(如
n,m,k的临时值),不随输入规模变化。 - 总的额外空间复杂度为 O(1)。
- 代码只使用了固定数量的变量(如
Go完整代码如下:
package main
import (
"fmt"
)
func minCuttingCost(n, m, k int) int64 {
return int64(max(k*(max(n, m)-k), 0))
}
func main() {
n := 6
m := 5
k := 5
result := minCuttingCost(n, m, k)
fmt.Println(result)
}
Python完整代码如下:
def min_cutting_cost(n: int, m: int, k: int) -> int:
return max(k * (max(n, m) - k), 0)
def main():
n = 6
m = 5
k = 5
result = min_cutting_cost(n, m, k)
print(result)
if __name__ == "__main__":
main()
C++完整代码如下:
#include <iostream>
#include <algorithm> // 用于std::max函数
// 函数计算最小切割成本
long long minCuttingCost(int n, int m, int k) {
// 计算n和m中的最大值
int max_val = std::max(n, m);
// 计算k * (max_val - k),并确保结果不小于0
long long value = static_cast<long long>(k) * (max_val - k);
return std::max(value, 0LL); // 返回value和0中的较大值
}
int main() {
int n = 6;
int m = 5;
int k = 5;
// 调用函数并输出结果
long long result = minCuttingCost(n, m, k);
std::cout << result << std::endl; // 输出应为5
return 0;
}