木材切割问题
一个木匠从木材公司买了一批木材,每块木材的长度均相同,但由于制作家具时所需的木块长度各不相同,因此需要把这些木材切割成长度不同的木块。同时每次切割时由于锯子本身有一定的宽度,因此每切割一次就会浪费掉一些木料。请设计一个程序使木匠能够用最少的木材切割出所需的木块。
输入描述:
输入有若干个测试样例,每个测试样例占一行。每行由若干个整数构成,第一个整数为所购买的木块的长度L$(0<L<=30000)$,第二个整数为锯子的宽度W$(0<W<=1000)$,其后的若干个整数分别表示制作家具时需要的木块的长度。
输出描述:
每个测试样例输出一行,为一个整数N,表示制作家具时需要购买的木块的数量。
样例输入:
1000 100 250 250 500 650 1000
1000 50 200 250 250 500 650 970
样例输出:
3
4
思路
这里先解决掉每次切割都会损耗锯子宽度的木材的问题。 给每个需要的木材加上锯子的宽度,然后给购买的木材的长度也加上一个木块的长度。这样就可以不考虑切割过程中锯子的损耗了。
然后就是贪心了,从木块中选择长度小于当前木料剩余长度的最大木块切割出去,如果没有一块小于当前木块了,那就用一块新的。消耗木材量加一。
代码
1 | import bisect |
回溯法
1 |
|
目标函数: min n n’L can split to len[] 最小的n,使的n个长度为L的木板能够分割为长度为数组len的木板。
目标函数的界限:size(len) 最多需要n个木料就能切割出n块木板。
约束条件:remain>=len[i] 剩余的木料长度大于等与需要切割的木板长度。
限界函数:当前使用木板数量+剩余需要切割木板数量 这里用的递归所以没用到限界函数。