用动态规划的自底向上方法解决钢材分割的问题。

#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);
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值