原理请参考 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");
}