1. 程式人生 > >貪心演算法----物品可分割的裝載問題----揹包問題

貪心演算法----物品可分割的裝載問題----揹包問題

  • 題目

有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);

    }
}
  • 結果