貪心演算法----物品可分割的裝載問題----揹包問題
阿新 • • 發佈:2018-12-16
-
題目
有n件物品和一個容量為m的揹包。第i件物品的重量是w[i],價值是v[i]。求解將哪些物品裝入揹包可使這些物品的重量總和不超過揹包容量,且價值總和最大。
- 思路
將價值 / 重量 的比值最大的優先放入揹包,所以先按比值排序,再一個個的往揹包裡放
- 程式碼
package com.algorithm; import java.util.Arrays; import java.util.Scanner; class Treasure implements Comparable<Treasure>{ private double w;//每個寶物的重量 private double v;//每個寶物的價值 double p;//價效比 public double getW() { return w; } public void setW(double w) { this.w = w; } public double getV() { return v; } public void setV(double v) { this.v = v; } public double getP() { return p; } public void setP(double p) { this.p = p; } boolean cmp(Treasure a, Treasure b){ return a.p > b.p;//根據寶物的單位價值從大到小排序 } @Override public int compareTo(Treasure o) { if(p < o.p) return -1; else if(p > o.p) return 1; else return 0; } } public class BookTest { public static void main(String[] args) { System.out.println("請輸入寶物的數量n及揹包的容量m"); Scanner sc = new Scanner(System.in); int n = sc.nextInt();//n表示有n個寶物 double m = sc.nextDouble();//m為揹包的容量 System.out.println("請輸入每個寶物的重量和價值,用空格分開"); Treasure[] tre = new Treasure[n]; for (int i = 0; i < n; i++){ tre[i] = new Treasure(); tre[i].setW(sc.nextDouble()); tre[i].setV(sc.nextDouble()); tre[i].setP(tre[i].getV() / tre[i].getW()); } System.out.println("寶物按價效比從小到大排序"); Arrays.sort(tre, 0, n); for(Treasure t : tre)// System.out.print(t.getP() + " "); System.out.println(); double sum = 0.0;//sum表示貪心記錄運走寶物的價值之和 for (int i = n-1; i >= 0 ; i--){ //tre[i] = new Treasure(); if(m > tre[i].getW())//按照排好的順序貪心 { m = m - tre[i].getW(); sum += tre[i].getV(); } else //如果寶物的重量大於揹包剩下的承載力 { sum += m * tre[i].p;//部分裝入 break; } } System.out.println("裝入寶物的最大價值是:" + sum); } }
- 結果