钢条切割————算法导论

给定长度任意长度的钢条的价值,求解如何切割,使给定长度为n的钢条的价值最大。
对于长度为n的钢条,考虑子问题,我们遍历1~n的第一个切割的位置j,即得到长度为j和n-j的两段钢条,第一段不再切割,仅对第二段继续切割,递归求解,于是就得到了一个递归解法。这里是C语言实现

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#define min -999999
#define maxsize 9999
int r[maxsize];//长度为n钢条最大价值
int cut_pop_recursive(int n, int p[]) {//暴力递归求解
	int i, j, k, max = min;
	if (n <= 1)return p[n];
	for (i = 1; i <= n; i++) {
		max = max > p[i] + cut_pop_recursive(n - i, p) ? max : p[i] + cut_pop_recursive(n - i, p);
	}
	return max;
}

但是可以看出时间复杂度极高为2^n。
不难发现,在求解过程中,重复求解了多次同样的子问题,因此不妨考虑将子问题的解存起来。
于是得到第二个解法

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#define min -999999
#define maxsize 9999
int r[maxsize];//长度为n钢条最大价值
void Memorized_cut_pop_init(int n) {//初始化
	int i;
	for (i = 0; i <= n; i++) {
		r[i] = min;
	}
	r[0] = 0;
}
int Memorized_cut_pop_recursive(int n, int p[]) {//自上而下
	int i, max = min;
	if (r[n] == min) {
		for (i = 1; i <= n; i++) {
			max = max > p[i] + Memorized_cut_pop_recursive(n - i, p) ? max : p[i] + Memorized_cut_pop_recursive(n - i, p);
		}
		r[n] = max;
	}
	return r[n];
}

这是一种自上而下的求解方法,时间复杂度为o(n^2)
下面是一种复杂度常系数更小的自下而上的解法

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#define min -999999
#define maxsize 9999
int r[maxsize];//长度为n钢条最大价值
void Memorized_cut_pop_init(int n,int p[]){
	int i;
	for(i=0;i<=n;i++){
		r[i]=min;
	}
	r[0]=0;
}
void Memorized_cut_pop(int n,int p[]){
	int i,j;
	for(i=1;i<n;i++){
		for(j=1;j<=n;j++){
			r[i]=r[i]>p[i]+r[i-j]?r[i]:p[i]+r[i-j];
		}
	}
}

ps:后两种解法调用前都需要初始化

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值