1. 程式人生 > >Java-01揹包問題-動態規劃-遞迴和非遞迴實現

Java-01揹包問題-動態規劃-遞迴和非遞迴實現

國際慣例,先上程式碼,粗略分析:

package com.bag;

/**
 * Author: lihao
 * Date:2017/8/31
 * Description:
 */
public class Main {
    static int totalweight= 150;
    static int N= 5;
    static int values[] = {60, 20, 10, 60, 100};
    static int weights[] = {20, 30, 50, 60, 80};

    public static void main(String[] args) {
        System.out.println(bagProblem(N-1,totalweight));
        bag01();
    }
    //遞迴實現
    // i {處理到第i件物品} , j{剩餘的空間為j}
    public static int bagProblem(int i, int j) {

        int r = 0;
        if(i==-1){
            return 0;
        }
        //如果剩餘空間大於所放的物品
        if (j>=weights[i]){
            int r1 = bagProblem(i-1,j-weights[i]) + values[i]; //放第i件
            int r2 = bagProblem(i-1,j);//不放第i件
            r = Math.max(r1,r2);
        }
        return r;

    }
    //非遞迴
    public static void  bag01(){
        int f[] = new int[totalweight+1];
        for (int f1:f){
            f1 = 0;
        }
        for (int i=0;i<N;i++){
            int w = weights[i];
            int v = values[i];
            for (int j= totalweight;j>=w;j--){
                f[j] = Math.max(f[j],f[j-w]+v);
            }
        }
        System.out.println(f[totalweight]);
    }
}



遞迴實現思路:

重點是尋找狀態轉移方程

int r1 = bagProblem(i-1,j-weights[i]) + values[i]; //放第i件
int r2 = bagProblem(i-1,j);//不放第i件
r = Math.max(r1,r2);

非遞迴實現思想:

建立0-totalweights共total+1大小的陣列,用來存放價值。

第一步,先任意拿一個物品,進行遍歷存放。

第二步,拿第二個物品,進行存放並且和之前的資料進行對比。存放大值。

以此類推,直至迴圈完成,取最後一個值,即為最大值。

舉例,揹包大小為10,物品有3個,重量和價值,分別是:3,4 4,5 5,6

第一次,放3,4,則陣列從a[0]到a[10]分別是: 

0 0 0 4 4 4 4 4 4 4 4 

第二次,放4,5,分別是

0 0 0 4 5 5 5 9 9 9  9

第三次,放5,6,分別是

0 0 0 4 5 6 6 9 10 11 11

迴圈完畢,a[10] = 11。

相關推薦

Java-01揹包問題-動態規劃-實現

國際慣例,先上程式碼,粗略分析: package com.bag; /** * Author: lihao * Date:2017/8/31 * Description: */ public class Main { static int totalwei

leetcode 783. 二叉搜尋樹結點最小距離(實現java)

題目描述: 給定一個二叉搜尋樹的根結點 root, 返回樹中任意兩節點的差的最小值。 示例: 輸入: root = [4,2,6,1,3,null,null] 輸出: 1 解釋: 注意,root是樹結點物件(TreeNode object),而不是陣列。 給定的樹 [4,

先序遍歷-java版)

用輔助棧就行儲存。   import java.util.Stack; class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null; publi

中序遍歷--java版)

根據中序遍歷的順序,對於任一結點,優先訪問其左孩子,而左孩子結點又可以看做一根結點,然後繼續訪問其左孩子結點,直到遇到左孩子結點為空的結點才進行訪問,然後按相同的規則訪問其右子樹。因此其處理過程如下:   對於任一結點root,引入一個輔助節點p,其作用是:標記已經訪問過的節點, &nb

Java——列印楊輝三角(

1.  非遞迴方法:  package com.zth; /** * 列印楊輝三角 * @author 時光·漫步 * */ public class SanJiao { public static void main(String[] args) {

Java資料結構:二叉樹的前序,中序,後序遍歷(

嚶嚶嚶,兩個月沒寫部落格了,由於有點忙,今天開始日更部落格。 今天總結一下學習樹的先根,中根,後根。每種兩種方法,遞迴和非遞迴。 先根: 遞迴: 思路:先根遍歷,即第一次遇到的結點就開始列印。先一直遍歷左子樹,直到未空,然後右子樹,直到為空。遞迴下去。 過程:先將1進入方法

二叉樹的先序遍歷()、中序遍歷()、後序遍歷()及層次遍歷java實現

二叉樹的先序遍歷,遞迴實現: public List<Integer> preorderTraversal(TreeNode root) { //用棧來實現 List<Integer> list = new ArrayList&l

C++ 01揹包 動態規劃

       圖片參考《演算法圖解》       假如你是一個小偷,你有一個4磅的揹包,你可以偷下面物品,如何保證你能獲得最大價值?     

JAVA實驗二:編碼實現一個類對輸入陣列的數從小到大排序同時使用二分法查詢某一個數(

編碼實現一個類 (1)提供一個靜態方法,可以將輸入的一個int[]陣列按照從小到大的順序排列; (2)提供靜態方法,對排好序的陣列使用折半(二分)查詢(使用遞迴和非遞迴兩種形式分別實現)查詢某一個整數。 答案 import java.util.*; public class

二叉樹的建樹、遍歷(先序、中序、後序、層次)()--Java實現

什麼是樹?什麼是二叉樹? 樹:除了根節點之外的所有節點都有且只有一個父節點,根節點沒有父節點;除了葉結點以外的所有節點,都有一個或多個子節點,葉結點沒有子節點。 二叉樹:是樹的一種特殊結構,在二叉樹中,每個節點最多隻能有兩個子

二叉樹的深度()---java實現

遞迴實現 為了求樹的深度,可以先求其左子樹的深度和右子樹的深度,可以用遞迴實現,遞迴的出口就是節點為空。返回值為0; 非遞迴實現 利用層次遍歷的演算法,設定變數level記錄當前節點所在的層數,設定變數last指向當前層的最後一個節點,當處理完當前層的最後一個節點,讓lev

Java(二分查詢演算法實現,分別使用方式)

public class BinarySearch { private int[] array; private int index; private int min; private int max; public BinarySearch(int[]

二分查詢 java實現

public static int rank(int []a , int x, int lo, int hi) { if(hi<lo) return -1; if(a[lo+(hi-lo)/2]>x) return rank(a,x,lo,lo+(hi-lo)/2-1);

斐波拉契數列的寫法(c/java

C語言版本:#include <stdio.h> long fib(long n) { if(n<=2) return(1); if(n>=3) return(fi

揹包問題的演算法

/** 簡單揹包問題 問題定義: 有一個揹包重量是S,有n件物品,重量分別是W0,W1...Wn-1 問能否從這n件物品中選擇若干件放入揹包中使其重量之和正好為S */ #include <iostream> #include <algorithm>

leetcode解題之21# Merge Two Sorted Lists Java實現

21. Merge Two Sorted Lists Merge two sorted linked lists and return it as a new list. The new li

java版 二叉樹 所有遍歷演算法

通過陣列構造二叉樹,所有遍歷演算法以及求二叉樹深度的遞迴演算法import java.util.LinkedList; public class BinaryTree { //根節點 private Node<Integer> root; //二

java實現二叉樹的遍歷(

現有一顆如下圖所示的二叉樹: 其遍歷的各種方式如下: 構造一顆如下圖所示的二叉樹,用java實現其前序,中序,後序遍歷 注意二叉樹節點的定義如下: public clas

Java實現快速排序

/** * 快速排序 * */ public class QuickSort{ /** * 遞迴一 * */ public static void sort1(int[] arr, int start, int end) { if(start &l

java實現求二叉樹深度

一.遞迴實現,深度優先遍歷二叉樹 public int dfs(TreeNode root){ if(null==root){ return 0;