#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
//用动态规划的自底向上的方法解决切钢条问题。
//问题:
//某公司出售一段长度为i英寸的钢条,公司希望把钢条切割后出售,切割不计成本,找出最优的切割方案。
//长度和价格的对应关系如下:
// 1-1;2-5;3-8;4-9;5-10;6-17;7-17;8-20;9-24;10-30;
#define max(x,y) ((x) > (y) ? (x) : (y))
/*
* price: prices array.
* length:the rod length.
* return: the best price.
*/
//自底向上切割钢条函数。
int bottom_top_cut_rod(const int price[],int length) {
int bestPrices[length+1]; //存储每个长度对应的最优价格。
int bestPosition[length+1]; //存储每个长度对应的最优切分方法的第一段。
int i,j,k;
if(length == 0) { //钢条长度为0,最优价格为0.
return 0;
}
memset(bestPrices,-1,(length+1) * sizeof(int));
memset(bestPosition,-1,(length+1)*sizeof(int));
bestPrices[0] = 0; //钢条长度为0,则最优价格为0.
//原理是从最小长度开始计算每一个长度的最优价格和最优分割方法,
//n+1长度的最优方法用到了n长度的最优方法。
for(i = 1;i <= length;i++) { //从1英寸开始,依次递增找出每个尺寸的最优价格和切割方法。
int temp = -1;
for(j = 1;j <= i;j++) { //找出i尺寸的最优价格和切割方法。
//temp = max(temp,price[j]+bestPrices[i-j]); //如果不存储切割方法的可以直接使用此函数替换下面的if语句。
if(price[j]+bestPrices[i-j] > temp) { //如果当前方法比上一个方法价格高
temp = price[j] + bestPrices[i-j]; //替换为当前价格。
bestPosition[i] = j; //记录下总长为i英寸时,价格最优时的第一段切割位置。
}
}
bestPrices[i] = temp; //记录i英寸的最优价格。
/*
printf("loop %d\n",i);
for(k = 0;k < 11;k++) {
printf("%d ",bestPrices[k]);
}
printf("\n");
*/
}
//output the best cut positions.
int cur = length; //打印length英寸时的最优切割方法。
while(cur) {
printf("%d ",bestPosition[cur]);
cur -= bestPosition[cur];
}
printf("\n");
return bestPrices[length]; //返回最优价格。
}
int main(void) {
int price[11] = {0,1,5,8,9,10,17,17,20,24,30}; //钢材的长度和价格比。
int result = bottom_top_cut_rod(price,10);
printf("The best price is %d\n",result);
exit(0);
}
用动态规划的自底向上方法解决钢材分割的问题。
最新推荐文章于 2022-12-08 18:09:55 发布