object WanQuanBeiBao2 extends App{
val num = 5
val volumn = 100
//法一
var beg = System.currentTimeMillis()
val thing = Array((92,77),(22,22),(87,29),(46,50),(90,99)) //(价值,重量)
// val volumn = 10
// val thing = Array((6,2),(3,2),(5,6),(4,5),(6,4)) //(价值,重量)
val table = new Array[Int](volumn+1)
def find(){ //最终的表:对于当前的容量,尽量用性价比最高的商品填充,剩余的容量再用对它来说性价比最高的商品填充,依次走一去,直到不能再填充商品。
for(i <- 0.until(num);j <- thing(i)._2.to(volumn).reverse;k <- 1.to(j/thing(i)._2))
if(table(j-k*thing(i)._2)+k*thing(i)._1 > table(j)) table(j) = table(j-k*thing(i)._2)+k*thing(i)._1
}
find()
println(table(volumn))
println("耗时(毫秒): " + (System.currentTimeMillis() - beg))
//法二:
var beg2 = System.currentTimeMillis()
val thing2 = Array((92,77),(22,22),(87,29),(46,50),(90,99)).sortWith((a:(Int,Int),b:(Int,Int)) => a._1/a._2.toDouble > b._1/b._2.toDouble)
val table2 = new Array[Int](volumn+1)
def find2(){ //将商品按性价比从高到低排序,能提高效率;这种改进使得动态规划与贪心算法很像。
for(i <- 0.until(num);j <- thing2(i)._2.to(volumn).reverse;k <- 1.to(j/thing2(i)._2))
if(table2(j-k*thing2(i)._2)+k*thing2(i)._1 > table2(j)) table2(j) = table2(j-k*thing2(i)._2)+k*thing2(i)._1
}
find2()
println(table2(volumn))
println("耗时(毫秒): " + (System.currentTimeMillis() - beg2))
//法三:二进制思想划分商品
var beg3 = System.currentTimeMillis()
val table3 = new Array[Int](volumn+1)
def find3(){
for(i <- 0.until(num);j <- thing2(i)._2.to(volumn).reverse){
var count = 0
for(k <- 0.to((math.log(volumn/thing2(i)._2)/math.log(2)).toInt).reverse){
val temp = math.pow(2,k).toInt
if(j-(count+temp)*thing2(i)._2 >= 0){ //可以放
if(table3(j-(count+temp)*thing2(i)._2)+(count+temp)*thing2(i)._1 > table3(j)){ //是否放
table3(j) = table3(j-(count+temp)*thing2(i)._2)+(count+temp)*thing2(i)._1
count += temp
}
}
}
}
}
find3()
println(table3(volumn))
println("耗时(毫秒): " + (System.currentTimeMillis() - beg3))
}
结果如下:
261
耗时(毫秒): 57
261
耗时(毫秒): 9
261
耗时(毫秒): 3