动态规划之钢条切割问题

动态规划用于解决最优化问题,即有很多可行解,每个解都有一个值,希望找到最优值(最大值或最小值)得解。

解决的问题具有最优子结构性质:最优解由相关子问题的最优解组合而成,子问题可独立求解。


问题描述:给定钢条,总长度为n,价格随长度i为Pi,求最大收益Rn。

问题分析:长度为n的钢条有2的n-1次方种切割方案。

          求解规模为n的原问题,县求解形式完全一样但规模更小的子问题。Rn=max(Pn,r1+rn-1,r2+rn-2.......rn-1+r1)

          还有一种递归方法求解(即只看右边):Rn=max(Pi+rn-i)(1<=i<=n),此时只包含一个相关子问题,是自顶向下的递归实现。但是效率差,n每增大1,运行时间会加一倍。

  

动态规划优化求解:有两种等价实现方法

                  带备忘录的自顶向下法

#include <iostream>
using namespace std;
int main()
{
int  n;
int P[100];
int R[100];
for(int i=1;i<101;i++)
{
	R[i]=-1;
}
}
int cut_rod(int P[],int n,int R[])
{
	if(R[n]>=0) return R[n];
	int r;
	if(n==0) r=0;
	else
	{
		r=-1;
		for(int i=1;i<=n;i++)
			r=max(r,P[i]+cut_rod(P,n-i,R));
	}
	R[n]=r;
	return r;
}

                  自底向上法
#include <iostream>
using namespace std;
int P[100];
int R[100];
int n;
int bottom_up_cut_rod(int P[],int n,int R[])
{
	R[0]=0;
	for(int j=1;j<=n;j++)
	{
		int r=-1;
		for(int i=1;i<=j;i++)
			r=max(r,P[i]+R[j-i]);
        R[j]=r;
	}
	return R[n];
}

                   

上面所求的结果为最优解的收益值,求解本身(一个长度列表,包含切割方案)则需扩展动态规划算法。

以自底向上的方法为例

#include <iostream>
using namespace std;
int P[100];
int R[100];
int S[100];
int n;
int bottom_up_cut_rod(int P[],int n,int R[])
{
	R[0]=0;
	for(int j=1;j<=n;j++)
	{
		int r=-1;
		for(int i=1;i<=j;i++)
			if(r<P[i]+R[j-i]) 
			{
				r=P[i]+R[j-i];
				S[j]=i;
			}
		R[j]=r;
	}
}
void print_cut_rod_solution(int P[],int R[])
{
	bottom_up_cut_rod(P,n,R);
	while(n>0)
	{
		printf("%d",S[n]);
		n-=S[n];
	}
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值