动态规划—钢条切割问题

动态规划里的钢条切割问题
长度i与价格pi的对应表为:
长度i  :1,2,3,4,5  ,6  ,7  ,8  ,9  ,10
价格pi:1,5,8,9,10,17,17,20,24,30
现在考虑给出一个长度为n英寸的钢条,通过动态规划找出最优的切割方案,以此达到最佳收益:
这里有两种方式能够解决该问题,一种是自顶向下带备忘的递归算法,一种是自底向上法(非递归),这里给出后者的算法(已通过测试):
#include<iostream>
#include<math.h>
#include<algorithm>
#define INF -999999
using namespace std;

void bottom_up_cut_rod(int *p, int n) {
	int *r = new int[n];          //创建一个新数组来保存子问题的解
	r[0] = 0;
	int i, j, q;
	for (j = 1; j <=n; j++) {
		q = INF;
		for (i = 0; i <= j; ++i) 
			q = max(q, p[i] + r[j - i-1]);
		r[j] = q;
	}
	cout << r[n] << endl;
}

int main() {
	int p[10] = { 1,5,8,9,10,17,17,20,24,30 };
	bottom_up_cut_rod(p, 5);
	system("pause");
	return 0;
}
这里以钢条长度等于5为例,输出结果为13,切割方案为5=2+3.

重构解:
以上给出的算法仅仅返回的是最优解,并没有给出解本身,现在添加信息,使每个子问题不仅返回最优解同时保存对应的切割方案。
下面的代码同样以上述数组为实例,并加上了切割位置,在VS2016已经通过测试:
#include<iostream>
#include<algorithm>
#define INF -999999
using namespace std;

void extended_bottom_up_cut_rod(int *p, int n) {
	int *r = new int[n];
	int *s = new int[n];
	r[0] = 0;
	int i, j, q;
	for (j = 1; j <= n; ++j) {
		q = INF;
		for (i = 0; i <= j; ++i) {
			if (q < p[i] + r[j - i - 1]) {
				q = p[i] + r[j - i - 1];
				s[j] = i+1;                      //标记切割位置(第几个)
			}
		}
		r[j] = q;
	}
	cout << "最优解是:" << r[n] << endl;
	cout << "第一个切割位置是:" << s[n] << endl;
}

int main() {
	int p[10] = { 1,5,8,9,10,17,17,20,24,30 };
	extended_bottom_up_cut_rod(p, 9);             //第二个参数可为1至10
	system("pause");
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值