#include <iostream>
#include <algorithm>
#include <vector>
#include <utility>
#include <limits.h>
using namespace std;
int memoryCutAux(vector<int> &p,int n,vector<int> &r)
{
int q;
if(r[n]>=0)
return r[n];
if(n==0)
q=0;
else
{
q=INT_MIN;
for(int i=1;i<=n&&i<p.size();i++)
q=max(q,p[i]+memoryCutAux(p,n-i,r));
}
r[n]=q;
return q;
}
//自顶向下的方法
int memoryCut(vector<int> &p,int n)
{
vector<int> r(n+1);
for (auto &v:r)
v=INT_MIN;
return memoryCutAux(p,n,r);
}
//自底向上的方法,过程求解的规模时j=0,1,..,n的子问题
int bottomUpCutRod(vector<int> &p,int n)
{
vector<int> r(n+1);
r[0]=0;
for(int j=1;j<=n;j++)
{
int q=INT_MIN;
for(int i=1;i<=j&&i<p.size();i++)
{
q=max(q,p[i]+r[j-i]);
}
r[j]=q;
}
return r[n];
}
/**扩展的自底向上方法
**返回的pair中first为保存0,1,..n长度钢条的最大化受益
**second的数组保存的是0,1...,n长度最优且分的第一段钢条的长度
*/
pair<vector<int>,vector<int>> ebottomUpCutRod(vector<int> &p,int n)
{
pair<vector<int>,vector<int>> result;
vector<int> r(n+1);
vector<int> s(n+1);
result.first.push_back(0);
result.second.push_back(0);
for(int j=1;j<=n;j++)
{
int q=INT_MIN;
//i<p.size()是因为当钢条长度大于我们价目表有的长度时,只能按价目表现有价格的最优解求取
for(int i=1;i<p.size()&&i<=j;i++)
{
if(q<p[i]+r[j-i])
{
q=p[i]+r[j-i];
s[j]=i;
}
}
r[j]=q;
result.first.push_back(r[j]);
result.second.push_back(s[j]);
}
return result;
}
//打印扩展的自底向上切分的结果
int printSolution(vector<int> &p,int n)
{
auto result=ebottomUpCutRod(p,n);
cout<<"Max Profit is: "<<endl;
cout<<result.first[n]<<endl;
cout<<"Cut scheme is: "<<endl;
while(n>0)
{
cout<<result.second[n]<<" ";
n-=result.second[n];
}
cout<<endl;
for(auto v:result.first)
cout<<v<<endl;
return 0;
}
主函数
#include "cutRod.h"
#include <vector>
#include <iostream>
using namespace std;
int main()
{
vector<int> p={0,1,5,8,9,10,17,17,20,24,30};
int ret=memoryCut(p,19);
int ret2=bottomUpCutRod(p,19);
cout<<ret<<endl;
cout<<ret2<<endl;
printSolution(p,19);
return 0;
}