问题描述:
Serling公司购买长钢条,将其切割为短钢条出售。切割工序本身没有成本支出。公司管理层希望知道最佳的切割方案。假定我们知道Serling公司出售一段长为i英寸的钢条的价格为pi(i=1,2,…,单位为美元)。钢条的长度均为整英寸。
| 长度i | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | | - | - | - | - | - | - | - | - | - | - |
价格pi | 1 | 5 | 8 | 9 | 10 | 17 | 17 | 20 | 24 | 30 |
钢条切割问题是这样的:给定一段长度为n英寸的钢条和一个价格表pi(i=1,2,…n),求切割钢条方案,使得销售收益rn最大。
注意,如果长度为n英寸的钢条的价格pn足够大,最优解可能就是完全不需要切割。
思路分析:
我们也可以使用贪心算法进行计算,把钢条长度和对应的价值进行类打包,然后重写compareto方法,把对象数组按照单位价值大小进行排序,进而得到最终j结果。
具体看代码注释:
import java.util.Arrays;
import java.util.Scanner;
public class Gtqg2 {
//钢条切割之贪心
private static class lv implements Comparable<lv>{
private int len;
private int val;
public lv(int len, int val) {//构造器
this.len = len;
this.val = val;
}
public double getval()//计算单位长度的价值
{
return this.val/(double)this.len;
}
@Override
public int compareTo(lv o) {//重写compareto方法
if (this.getval()-o.getval()>0)return 1;
else if (this.getval()-o.getval()<0) return -1;
else
return this.len-o.len;
}
@Override
public String toString() {
return this.len+" "+this.val;
}
}
public static void main(String[] args) {
Scanner a=new Scanner(System.in);
int []len={1,2,3,4,5,6,7,8,9,10};
int []val={1,5,8,9,10,17,17,20,24,30};
int lens=a.nextInt();//输入要切割的长度
lv []lvs=new lv[len.length];//对象数组初始化
for (int i = 0; i <len.length ; i++) {
lvs[i]=new lv(len[i],val[i]);
}
Arrays.sort(lvs);//对对象数组进行单位长度价值排序
System.out.println(Arrays.toString(lvs));
int res=0;//记录最大价值
for (int i = lvs.length-1; i >=0 ; i--) {
if (lvs[i].len<=lens&&lens>0)
{
int temp=lens/lvs[i].len;//记录某一长度切割次数
res+=lvs[i].val*temp;//记录价值
lens-=temp*lvs[i].len;
if (lens==0)//长度为0,直接退出
break;
}
}
System.out.println(res);
}
}
运行结果如下:
倒数第二行为按照单位价值大小排序后的对象数组。