关于最优切割问题

  • 对最优切割问题的分析

问题描述:一家公司购买长钢条,将其切割成短钢条出售,假设切割本身没有成本,长度为i的短钢条的价格为Pi。那给定一段长度为n的钢条和一个价格表Pi,求钢条的切割方案使得收益Rn最大。例如某公司以单价26元买到了一批长度为10的钢条,目前各长度钢条的市场价如下表所示:

长度i

1

2

3

4

5

6

7

8

9

10

价格Pi

1

5

8

9

10

17

17

20

24

26

要求:随机生成钢条长度n和不同长度钢条的价格信息,编写程序确定一种钢条的切割方案,使公司的收益最大化。

使收益最大化就是将钢条切割成两段,然后求出这两段的价格最大值,就是最优解,随机生成长度和每段的价格,考虑所有可能。

  • 算法选择以及设计思路

通常用于具有某种最优性质问题,对于本题而言,最后让求出收益的最大化。对于这个题

一方面体现了最优解又一方面体现了算法求解相同的子问题。使用动态规划算法时,用子问题的最优解来构造原问题的最优解和使用数组来保存子问题的解。动态规划与其他算法相比较而言,灵活性强,计算量大大减少了,但是对空间的需求增加了,本题因为所需空间不大,所以采用这种算法。

对于一个动态规划问题:

第一步就是先确定最优解的结构。如果一个问题的结构包含其子问题的最优解,就称此问题具有最优解的结构性质。使用动态规划算法时,用子问题的最优解来构造原问题的最优解。因此必须考查最优解中用到的所有子问题。

第二步定义最优解的计算公式。

第三步是根据得到的求解最优解公式,计算出结果。

第四步是构造出最优解。

#include <stdlib.h>
#include <stdio.h>
#include <time.h>
int N[11]={};//存储价格 
int r[11]={};
int upToDown(int);
int maxx(int a,int b);
int main()
{	
	int z,x,c,a[11]={0};
	printf("钢条长度:"); 
	for(z=0;z<=10;z++)
	printf("%3d",z);
	//随机数生成,生成不同钢条长度的不同价格 
	
	srand((unsigned)time(NULL));
	for(z=0;z<=10;z++)
	{
		a[z]=rand()%(25)+4;
	}
	printf("\n");
	for(z=0;z<=9;z++)
		for(x=z+1;x<=10;x++)
		{
			if(a[z]>a[x])
			{
				c=a[z];
				a[z]=a[x];
				a[x]=c;
			}
		}
		a[0]=0;
		a[1]=1,a[2]=4,a[3]=7;
		printf("钢条价格:");
	for(z=0;z<=10;z++)
		N[z]=a[z];
		
		for(z=0;z<=10;z++)
			printf("%3d",a[z]);
		
	//对钢条进行切割计算				
	int current;
	puts("\n输入你要裁剪的钢条长度:");
	scanf("%d",&current);
	int i;
	printf("%d长的钢条最大收益是:%d\n",current,upToDown(current));
	printf("各个长度的收益情况:\n长度:");
	for(i=0;i<=current;i++)
	{
		printf("%3d ",i);
	}
	printf("\n");
	printf("收益:");
	for(i=0;i<=current;i++)
	{
		printf("%3d ",r[i]);
	}
} 
int upToDown(int n) //每次返回的值是当前长度n的最大收益 
{
	
		
	if(n==0)
		return 0;

	int q=N[n];	
	int i;
	for(i=1;i<n;i++)
		q=maxx(q,r[i]+upToDown(n-i));
	r[n]=q;
	if(r[n]!=0)
		return r[n];
	return q;
}
int maxx(int a,int b)//比较大小 
{
	if(a>=b)
		return a;
	else
return b;}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值