一、项目描述
某汽车需要用若干规格的轴各一根,这些轴的规格分别是a1米,a2米,…,an米(1.5米、1米、0.7米),这些轴需要用同一种圆钢来做,圆钢长度为SL米(如4米),有多少种下料方案,这些方案中余料最少的方案是哪种。(每种下料方案中可以包括规格中的一部分或全部)提示:用动态规划或回溯法(按0-1背包)解决。
二、算法设计
a. 轴的规格分别是a1米,a2米,…,an米,圆钢长度为SL米,用n表示车轴规格个数,SL表示圆钢起始长度,L表示去掉最可能情况后最大长度 ,bestl表示车轴当前最大长度 ,l[i]表示车轴规格长度,x[i]暂存某规格车轴的选中情况,len当前所选车轴总长度
b. 用递归函数Backtrack(int i,int len)来实现回溯法搜索子集树(形式参数i表示递归深度,n用来控制递归深度,形式参数i和len表示当前总价值和总重量,bestp表示当前最优总价值):
① 若i >n,则算法搜索到一个叶结点,判断当前长度是否最优:
1> 若len>bestl&&len<L,更新当前最优总长度为bestl=len;,更新装载方案(即bestx[i]=xi);
2> 若总长度不大于圆钢长度(即len+x[i]*l[i]<=L),则更新当前总长度(即len+=l[i]*x[i]; ), 对物品i+1调用递归函数Backtrack(int i,int len)继续进行装载;
3> 函数Backtrack(int i,int len)调用结束后则返回当前总长度(即 len+=l[i]*x[i];);
4> 当j>1时,for循环结束;
③ 当i=1时,若已测试完所有装载方案,外层调用就全部结束;
c. 主函数调用一次Backtrack(1,0)即可完成整个回溯搜索过程,最终得到的bestl和bestx[i]即为所求最大总长度和最优装载方案。
三、程序
#include<stdio.h>
int n,SL,L,bestl; //车轴规格个数,圆钢长度,最大长度
int l[10000],x[10000],bestx[10000]; //车轴规格长度,x[i]暂存某规格车轴的选中情况
void Backtrack(int i,int len) /