您的位置:首页 > 其它

[算法学习笔记]动态规划之钢条切割问题

2016-08-05 14:10 393 查看

问题描述

有一个长度为n的钢条需要切割成短钢条出售,长度不同的钢条售价也不同,如下:

长度i12345678910
价格p[i]1589101717202430
那么怎么切割才能获得最大利益呢

暴力解决思路

只要列出每种切割方案,然后比较一下哪种切割方案利润最大不就可以了吗(手动滑稽

假设有一个长度为4的钢条,那么有一下四中切割方案

编号切割方案利润
■■■■9
■■■,■9
■■,■■10
■■,■,■6
■,■,■,■4
发现当钢条长度为4时,切割成两个长度为2的短钢条利润最大。而且当切割钢条时,若切割完成后的钢条长度小于等于1的话,则可以把这个钢条看成规模更小的相同问题,用同样的方法先求出这个短钢条的最大利润,然后比较所有组合的利润,构成原问题的解。

钢条切割问题满足最优子结构的性质:问题的最优解由相关问题的最优解组合而成,而这些子问题可以独立求解。

通过递归的求解方式可以写出简单的求解程序:从钢条的左边切割下一段长度为i的短钢条,然后右边为长度就为n-i的短钢条,然后对右边继续递归求解,知道右边的长度为0,则返回零。

#include <stdio.h>
#define max(a,b) (a>b?a:b)
#define INF 0x7fffff;

// 不同长度钢条的价格
int p[11] = {
0,1,5,8,9,10,17,17,20,24,30
};

int cutROd(int p[], int n){
int i, q;
if(n == 0)
return 0;
q = -INF;
for(i = 1; i <= n; i++){
q = max(q, p[i] + cutROd(p, n - i));
}

return q;
}

int main(){
int n;
scanf("%d", &n);
printf("%d\n", cutROd(p, n));

return 0;
}


指数爆炸

图样图森破啊,这个程序的复杂度是2^n,所以输入大一点的数就会指数爆炸了,等半天结果才会出来,所以这样写太native了

更高效的方法

改进上面的程序

上面的程序之所以低效,因为有很多重复的计算啊,比如说计算长度为4的钢条,便有多次计算了长度为2和3的最优解,更不要说在大一点的数要重复计算多少次了。但是,如果能避免这些重复计算的,算法的效率就会非常高了,只要在第一次计算中吧结果记录下来,下次需要用到的时候直接调用就可以了。

#include <stdio.h>
#define max(a,b) (a>b?a:b)
#define INF 0x7fffff;

int p[11] = {
0,1,5,8,9,10,17,17,20,24,30
};

int memoizedCutRodAux(int p[], int n, int r[]){
int q;
if(r
>= 0)
return r
;
if(n == 0)
q = 0;
else{
q = -INF;
int i;
for(i = 1; i <= n; i++)
q = max(q, p[i] + memoizedCutRodAux(p, n-i, r)) ;
}
r
= q;
return q;
}

int memoizedCutRod(int p[], int n){
int r[11], i;
for(i = 0; i < 11; i++)
r[i] = -INF;
return memoizedCutRodAux(p, n, r);
}

int main(){
int n;
scanf("%d", &n);
printf("%d\n", memoizedCutRod(p, n));

return 0;
}


另一种解法

#include <stdio.h>
#define max(a,b) (a>b?a:b)
#define INF 0x7fffff;

int p[11] = {
0,1,5,8,9,10,17,17,20,24,30
};

int buttomUpCutRod(int p[], int n){
int r[n+1];
r[0] = 0;
int i, j;
for(i = 1; i <= n; i++){
int q = -INF;
for(j = 1; j <= i; j++)
q = max(q, p[j] + r[i - j]);
r[i] = q;
}

return r
;
}

int main(){
int n;
scanf("%d", &n);
printf("%d\n", buttomUpCutRod(p, n));

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  动态规划 算法