《算法导论》——动态规划 钢条切割

原理请参考 https://blog.youkuaiyun.com/yangtzhou/article/details/80518305

#include "iostream"
#include "math.h"
#include "algorithm"
using namespace std;

//自顶向下递归求解法(时间最长)
int CUT_ROD(int* p, int n)//p为价目表,n为长度
{
	if (n == 0)
		return 0;
	int q = INT_MIN;//收益
	for (int i = 1; i <= n; i++)
	{
		int m = p[i] + CUT_ROD(p, n - i);
		if (q < m )
		{
			q = m;
		}
		
	}
	return q;       
}

//带备忘录的自顶向下递归算法
int MEMOIZED_CUT_ROD_AUX(int* p, int n, int* r, int* solu)//r记录各长度的最优解
{
	int q;//利润
	int s=0;//从第几段开始划分
	if (r[n] >= 0)
		return r[n];
	if (n == 0)
		q = 0;
	else
	{
		q = INT_MIN;
		for (int i = 1; i <= n; i++)
		{
			int m = p[i] + MEMOIZED_CUT_ROD_AUX(p, n - i, r, solu);
			if (q < m)
			{
				q = m;
				s = i;
			}
		}
	}
	r[n] = q;
	solu[n] = s;//存储不同长度的划分方案
	return q;

}
int MEMOIZED_CUT_ROD(int* p, int n,int* r, int* solu)//p价格表
{

	memset(solu, 0, sizeof(int)*(n+1));
	for (int i = 0; i <=n; i++)
	{
		r[i] = INT_MIN;
	}
	return MEMOIZED_CUT_ROD_AUX(p, n, r,solu);
}

void main1()
{
	int p[] = {0,1,5,8,9,10,17,17,20,24,30};
	int n;
	cout << "输入钢条长度" << endl;
	cin >> n;
	int* r = new int[n+1]; //存放最优解的值
	int* solu = new int[n+1];//存放长度为n的第一段划分方案

	cout << "---自顶向下的递归方案---" << endl;
	int sal = CUT_ROD(p, n);
	cout << sal << endl;

	cout << "---带备忘录的自顶向下递归方案---" << endl;
	int sal1 = MEMOIZED_CUT_ROD(p, n, r, solu);
	cout << "不同长度的钢条最优切割方式的第一段长度" << endl;
	for (int i = 0; i <= n; i++)
	{
		cout << solu[i] << " ";
	}
	cout << endl;

	cout << "不同长度钢条的最大收益" << endl;
	for (int i = 0; i <= n; i++)
	{
		cout << r[i] << " ";
	}
	cout << endl;

	cout << "长度为" << n << "的最大收益为"<<r[n]<<" "<<"方案如下" << endl;
	while (n > 0)
	{
		cout << solu[n] << " ";
		n = n - solu[n];	}

	system("pause");
}

动态规划解决

#include "iostream"
using namespace std;

void BOTTOM_UP_CUT_ROT(int* a,int n,int* r1, int* slou1)
{
	int i = 0, j = 0;
	r1[0] = 0;
	int q;//收益
	for (i = 1; i <= n; i++)
	{
		q = INT_MIN;
		for (j = 1; j <= i; j++)
		{
			int m = a[j] + r1[i - j];
			if (q < m)
			{
				q = m;
				slou1[i] = j;
			}
		}
		r1[i] = q;
	}
}
void main()
{
	int a[] = { 0,1,5,8,9,10,17,17,20,24,30 };
	int n1;
	cout << "输入钢材长度" << endl;
	cin >> n1;
	int *r1 = new int[n1 + 1];//存放不同长度钢材的最佳收益
	int* slou1 = new int[n1 + 1];//存放不同长度钢材最佳收益的第一段切割方案
	memset(r1, 0, 4 * (n1 + 1));
	memset(slou1, 0, 4 * (n1 + 1));
	BOTTOM_UP_CUT_ROT(a, n1, r1, slou1);
	cout << "不同长度钢材的最佳收益" << endl;
	for (int i = 0; i <= n1; i++)
	{
		cout << r1[i] << " ";
	}
	cout << endl;
	cout << "长度为" << n1 << "的最大收益为" << r1[n1] << " " << "方案如下" << endl;
	while (n1 > 0)
	{
		cout << slou1[n1] << " ";
		n1 = n1 - slou1[n1];
	}

	system("pause");
	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值