自底向上法:这种方法一般需要恰当定义子问题“规模”的概念,使得任何子问题的求解都依赖于“更小的”子问题的求解。因而我们可以将子问题按规模排序,按由小至大的顺序进行求解。当求解某个子问题时,它所依赖的那些更小的子问题都已经求解完毕,结果已经保存。每个子问题只需要求解一次,当我们求解它(也是第一次遇到它)时,它的所有前提子问题都已求解完成。
问题:公司购买长钢条,将其切割为短钢条出售。切割工序本身没有成本支出。公司管理层希望知道最佳的切割方案。
假定我们知道公司出售一段长度i英寸的钢条的价格为pi(i=1,2,...,单位为美元)。钢条的长度均为整英寸。图给出了一个价格表的样例。
(借用了图)
//Rn = max{pn,R1+Rn-1,R2+Rn-2,...}
//简化版本 Rn = max(Pi+Rn-i),1<=i<=n
自底向上的伪代码:
BOTTOM-UP-CUT-ROD(p,n) 1 let r[0..n]be a new array 2 r[0]=0 3 for j=1 to n 4 q=-1 5 for i=1 to j 6 q=max(q,p[i]+r[j-i]) 7 r[j]=q 8 return r[n]
// Gangjinqiege.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <IOSTREAM>
#include <VECTOR>
using namespace std;
//Rn = max{pn,R1+Rn-1,R2+Rn-2,...}
//简化版本 Rn = max(Pi+Rn-i),1<=i<=n
//1,5,8,9,10,17,17,20,24,30
//1,2,3,4,5 ,6 ,7 ,8 ,9 ,10
int max(int a,int b){
return a>b?a:b;
}
//p只有10个元素,切割的钢条总长度需<=10
int p[10] = {1,5,8,9,10,17,17,20,24,30};
int getMaxValue(int n){
vector<int> array(n+1,0);
// array.resize(n+1);
int i = 0,j = 0;
for(i = 1;i<n+1;i++){
int q = 0;
for(j = 1;j<=i;j++){
q = max(q,p[j-1] + array[i-j]);
}
array[i] = q;
// cout<<q<<" ";
}
// cout<<endl;
//array[1] = max{p[0]+array[0]}
//array[2] = max{p[0]+array[1],p[1]+array[0]}
//array[3] = max{p[0]+array[2],p[1]+array[1],p[2]+array[0]}
// for( i = 0;i<n+1;i++)
// cout<<array[i]<<" ";
cout<<endl;
return array[n];
}
int main(int argc, char* argv[])
{
for(int i = 1;i<11;i++)
cout<<"i = "<<i<<" value = "<<getMaxValue(i)<<endl;
return 0;
}