C++实现算法导论十五章动态规划之钢条分割问题

#include<iostream>
#include<algorithm>
#include<utility>
#include<vector>
using namespace std;
//采用普通的递归算法来求解钢条分割的最大的收益
int cut_rod(int *p,const int &n)
{
	if(n==0)
		return 0;
	int q=-1;
	for(int i=1;i<=n;++i)
	{
		q=max(q,p[i]+cut_rod(p,n-i));
	}
	return q;
}
//采用至顶向下的函数的动态规划函数方法来求解该问题
int memoized_cut_rod_aux(int *p,int n,int *r)
{
	if(r[n]>=0)
	{
		return r[n];
	}
	int q=-1;
	if(n==0)
		q=0;
	else
	{
		for(int i=1;i<=n;++i)
			q=max(q,p[i]+memoized_cut_rod_aux(p,n-i,r));

	}
	r[n]=q;
	return q;
}
//至顶向下发的主函数
int memoized_cut_rod(int *p,int n)
{
	int r[11]={};
	for(int i=0;i<11;++i)
		r[i]=-1;
	int q=memoized_cut_rod_aux(p,n,r);
	return q;

}
//至顶向上的方法来求解钢条问题
int bottom_up_cut_rod(int *p,int n)
{
	int r[11]={0};
	for(int j=1;j<=n;++j)
	{
		int q=-1;
		for(int i=1;i<=j;++i)
		{
			q=max(q,p[i]+r[p,j-i]);
		}
		r[j]=q;
	}
	return r[n];
}
  pair< vector<int>,vector<int> >  extened_bottom_up__cut_rot(int *p,int n)
  {
	 pair< vector<int>,vector<int> > result;
	  int  r[11]={0};
	  int s[11]={0};
	  result.first.push_back(0);
	  result.second.push_back(0);
	  for(int j=1;j<=n;++j)
	  {
		  int q=-1;
		  for(int i=1;i<=j;++i)
		  {
			   //q=-1;
			  //q=max(q,p[i]+r[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;
  }
  //打印结果值;
  void print_cut_rod_solution(int *p,int n)
  {
	  cout<<"最大的收益值为"<<endl;

	  //cout<<"钢条的分割方式为"<<endl;
	  pair< vector<int>,vector<int> > result;
	  result=extened_bottom_up__cut_rot(p,n);
	  cout<<result.first[n]<<endl;
	  cout<<"钢条的分割方式为"<<endl;
	  while(n>0)
	  {
		  //cout<<"钢条的分割方式为"<<endl;
		  cout<<result.second[n];
		  n=n-result.second[n];
		  cout<<endl;
	  }
	  cout<<endl;
	  cout<<"钢条的分割方式结束"<<endl;
  }

int main()
{
	int price[11]={0,1,5,8,9,10,17,17,20,24,30};
	//cout<<cut_rod(price,5)<<endl;
	cout<< bottom_up_cut_rod(price,8)<<endl;
	print_cut_rod_solution(price,8);
	system("pause");
	return 0;
}

时间: 2024-11-05 15:51:13

C++实现算法导论十五章动态规划之钢条分割问题的相关文章

算法导论第十五章动态规划

概述: 1.动态规划是通过组合子问题的解而解决原问题的. 2.动态规划适用于子问题不是独立的情况,也就是各子问题的包含公共的子子问题. 3.动态规划对每个子问题只求解一次,将其结果保存在一张表中. 4.动态规划的设计步骤:a.描述最优解的结构b.递归定义最优解的值c.按自底向上的方式计算最优觖的值d.由计算出的结构构造一个最优解 15.1钢条切割 钢条切割问题:给定定长的钢条和价格表,求切割方案,使得收益最大.如果n英寸的钢条的价格足够大,则不需要切割. 代码如下: //朴素递归求解钢条切割收益

第十五章 动态规划——矩阵链乘法

前言:今天接着学习动态规划算法,学习如何用动态规划来分析解决矩阵链乘问题.首先回顾一下矩阵乘法运算法,并给出C++语言实现过程.然后采用动态规划算法分析矩阵链乘问题并给出C语言实现过程. 1.矩阵乘法 从定义可以看出:只有当矩阵A的列数与矩阵B的行数相等时A×B才有意义.一个m×r的矩阵A左乘一个r×n的矩阵B,会得到一个m×n的矩阵C.在计算机中,一个矩阵说穿了就是一个二维数组.一个m行r列的矩阵可以乘以一个r行n列的矩阵,得到的结果是一个m行n列的矩阵,其中的第i行第j列位置上的数等于前一个

算法导论笔记——第十五章 动态规划

通常用来解决最优化问题.在做出每个选择的同时,通常会生成与原问题形式相同的子问题.当多于一个选择子集都生成相同的子问题时,动态规划技术通常就会非常有效.其关键技术就是对每个这样的子问题都保存其解,当其重复出现时即可避免重复求解. 分治:划分为互不相交的子问题,递归求解子问题,再将他们的解组合起来. 动态规划(dynamic programming,表格法而非编程)用于子问题重叠的情况. 四个步骤来设计一个动态规划算法: 1 刻画一个最优解的结构特征 2 递归地定义最优解的值 3 计算最优解的值,

第十五章 动态规划——钢条切割

前言:动态规划的概念 动态规划(dynamic programming)是通过组合子问题的解而解决整个问题的.分治算法是指将问题划分为一些独立的子问题,递归的求解各个问题,然后合并子问题的解而得到原问题的解.例如归并排序,快速排序都是采用分治算法思想.本书在第二章介绍归并排序时,详细介绍了分治算法的操作步骤,详细的内容请参考:http://www.cnblogs.com/Anker/archive/2013/01/22/2871042.html.而动态规划与此不同,适用于子问题不是独立的情况,也

第十五章 动态规划——最长公共子序列

1.基本概念 一个给定序列的子序列就是该给定序列中去掉零个或者多个元素的序列.形式化来讲就是:给定一个序列X={x1,x2,……,xm},另外一个序列Z={z1.z2.……,zk},如果存在X的一个严格递增小标序列<i1,i2……,ik>,使得对所有j=1,2,……k,有xij = zj,则Z是X的子序列.例如:Z={B,C,D,B}是X={A,B,C,B,D,A,B}的一个子序列,相应的小标为<2,3,5,7>.从定义可以看出子序列直接的元素不一定是相邻的. 公共子序列:给定两个

【算法导论第五章】课后习题解析

---恢复内容开始--- 5.1-1证明:假设在程序HIRE-ASSISTANT的第4行中,我们总是能够决定哪一个应聘者最佳,则意味着我们知道应聘者排名的总次序 既然我们总是能够决定哪一个应聘者最佳,想必我们已经对应聘者进行比较了,既然已经进行比较,排序就不应是个问题,既然可以进行排序,总次序也就可以知道了 5.1-2描述RANDOM(a,b)过程的一种实现,它只调用RANDOM(0,1).作为a和b的函数,你的程序的期望运行时间是多少? 没看懂,不会做 5.2-1 分析: 由5.1节中概率分析

算法导论 第13章 红黑树

二叉查找树的基本操作包括搜索.插入.删除.取最大和最小值等都能够在O(h)时间复杂度内实现,因此能在期望时间O(lgn)下实现,但是二叉查找树的平衡性在这些操作中并没有得到维护,因此其高度可能会变得很高,当其高度较高时,而二叉查找树的性能就未必比链表好了,所以二叉查找树的集合操作是期望时间O(lgn),最坏情况下为O(n). 红黑树也是一种二叉查找树,它拥有二叉查找树的性质,同时红黑树还有其它一些特殊性质,这使得红黑树的动态集合基本操作在最坏情况下也为O(lgn),红黑树通过给节点增加颜色和其它

《Java并发编程实战》第十五章 原子变量与非阻塞同步机制 读书笔记

一.锁的劣势 锁定后如果未释放,再次请求锁时会造成阻塞,多线程调度通常遇到阻塞会进行上下文切换,造成更多的开销. 在挂起与恢复线程等过程中存在着很大的开销,并且通常存在着较长时间的中断. 锁可能导致优先级反转,即使较高优先级的线程可以抢先执行,但仍然需要等待锁被释放,从而导致它的优先级会降至低优先级线程的级别. 二.硬件对并发的支持 处理器填写了一些特殊指令,例如:比较并交换.关联加载/条件存储. 1 比较并交换 CAS的含义是:"我认为V的值应该为A,如果是,那么将V的值更新为B,否则不需要修

算法&lt;初级&gt; - 第五章 递归与动规相关问题(完结)

算法<初级> - 第五章 递归与动规相关问题(完结) <一>递归和动态规划 暴力递归 转化为规模缩小了的同问题的子问题 - 时间复杂度O(2n-1) 有明确的边界条件(base case) - 先写base case,再写问题递归的过程 有得到子问题结果后决策过程 不记录每个子问题的解 - 每次求解子问题都交给递归去解决,不会在全局保存子问题的解(与动规形成对比) 动态规划DP 从暴力递归中延申 - 过程中还经历过<记忆化搜索>,相当于暴力递归+cache缓存(用has