动态规划方法通常用来求解最优化问题。动态规划算法设计步骤:
1.刻画一个最优解的结构特征。
2.递归定义最优解的值。
3.计算最优解的值,通常采用自底向上的方法。
4.利用计算出的信息构造一个最优解。
动态规划的实现方法:
带备忘的自顶向下法:此方法仍按自然的递归形式编写过程,但过程会保存每个子问题的解(通常保存在一个数组或散列表中)。当需要一个子问题的解时,过程首先检查是否已经保存过此解。如果是,则直接返回保存的值,从而节省了计算时间;否则,按通常方式计算这个子问题。
自底向上法:这种方法一般需要恰当定义子问题“规模”的概念,使得任何子问题的求解都依赖于“更小的”子问题的求解。因而我们可以将子问题按规模排序,按由小至大的顺序进行求解。当求解某个子问题时,它所依赖的那些更小的子问题都已经求解完毕,结果已经保存。每个子问题只需要求解一次,当我们求解它(也是第一次遇到它)时,它的所有前提子问题都已求解完成。
问题:公司购买长钢条,将其切割为短钢条出售。切割工序本身没有成本支出。公司管理层希望知道最佳的切割方案。
假定我们知道公司出售一段长度i英寸的钢条的价格为pi(i=1,2,...,单位为美元)。钢条的长度均为整英寸。图给出了一个价格表的样例。
自底向上的伪代码:
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]
整个程序的实现为:
#include <iostream> #include <vector> using namespace std; void print_s(vector<int> s, int n); //钢条切割动态规划之自底向上 vector<int> Bottom_Up_Cut_Rod(vector<int> price, int n); int main() { int i = 0; int a[11] = {0,1,5,8,9,10,17,17,20,24,30}; vector<int> price; while(i < 11) { price.push_back(a[i]); i++; } vector<int> s(Bottom_Up_Cut_Rod(price, 8)); cout<<"The best cut :"; print_s(s, 8); return 0; } vector<int> Bottom_Up_Cut_Rod(vector<int> price, int n) { vector<int> result(n+1, -1); vector<int> s(n+1, -1); int i, j, q; result[0] = 0; s[0] = 0; for(i = 1; i < n+1; i++) { q = -1; for(j = 1; j < i+1; j++) if(q < price[j]+result[i-j]) { q = price[j] + result[i-j]; s[i] = j; } result[i] = q; } cout<<"The max profit :"<<result[n]<<endl; return s; } void print_s(vector<int> s, int n) { while(n) { cout<<s[n]<<"\t"; n = n - s[n]; } }
动态规划之钢条切割
时间: 2024-10-10 23:15:26