1. 程式人生 > >動態規劃--0-1揹包問題1

動態規劃--0-1揹包問題1

package com.duoduo.day316;
/**
 * 0-1揹包問題
 * 
 * 問題描述:有n個物品,每個物品的重量為w[i], 價值為v[i],購物車容量為W,選擇若干個物品放入購物車
 * 限制:在不超過容量的前提下使獲得的價值最大
 * 思路:和之前的貪心演算法(揹包問題)不同,故分析最優子結構後,採用動態規劃思想求解
 * 
 * c[i][j]: 前i件物品放入一個容量為j的購物車可以獲得的最大價值
 *        購物車容量不足,肯定不能放入:
 *       c[i][j]=  c[i-1][j]    j<wi
 *        購物車容量足,看放入,不放入哪種情況獲得的價值最大:
 *       c[i][j]=  max{c[i-1][j],c[i-1][j-w[i]]+v[i]    j>=wi
 *       
 * @author 多多
 *
 */
import  java.util.Scanner;
public class Test4_9 {
	public static void main(String [] args) {
		Scanner sc=new Scanner(System.in);
		System.out.println("請輸入物品的個數n:");
		int n=sc.nextInt();      //物品的個數
		System.out.println("請輸入購物車的容量:");
		int W=sc.nextInt();
		System.out.println("請依次輸入每個物品的重量 w 和價值 v,用空格分開:");
		int [] w=new int[n+1];     //每個物品的重量
		int [] v=new int[n+1];     //每個物品的價值
		for(int i=1;i<=n;i++) {    //存入鍵入的資料
			w[i]=sc.nextInt();
			v[i]=sc.nextInt();
		}
		
		int [][] c=new int[n+1][W+1];  //c[i][j] : 前i件物品放入一個容量為j的購物車可以獲得的最大價值
		//初始化陣列 c[i][j]
		for(int i=0;i<=n;i++)          
			c[i][0]=0;
		for(int j=0;j<=W;j++)
			c[0][j]=0;
		
		/*計算c[i][j]的遞迴式
		購物車容量不足,肯定不能放入:
		        c[i][j]=  c[i-1][j]                j<wi
	        購物車容量足,看放入,不放入哪種情況獲得的價值最大:
		        c[i][j]=  max{c[i-1][j],c[i-1][j-w[i]]+v[i]   j>=wi
		*/
		
		for(int i=1;i<=n;i++) {
			for(int j=1;j<=W;j++) {
				if(j<w[i]) {
					c[i][j]=c[i-1][j];  //購物車容量不足,肯定不能放入:
				}else {
					c[i][j]=max(c[i-1][j],c[i-1][j-w[i]]+v[i]);//購物車容量足,看放入,不放入哪種情況獲得的價值最大:
				}	
			}
		}
		System.out.println("裝入購物車的最大價值:"+c[n][W]);
		
		/*逆向構造最優解
		 * 根據c[i][j]陣列的計算結果  逆向  逆推 用一個一維陣列x[]記錄解向量  
		 * x[i]=1  表示第i個物品放入購物車
		 * x[i]=0  表示不放入購物車 
		 * */
		int [] x=new int[n+1];
		int j=W;
		for(int i=n;i>0;i--) {
			if(c[i][j]>c[i-1][j]) {  //說明第i個物品放入購物車 標記為1 且 購物車容量--物品重量
				x[i]=1;
				j-=w[i];
			}else {
				x[i]=0;             //否則 未放入 則標記為0
			}
		}
		
		System.out.println("裝入購物車的物品為:");
		for(int i=1;i<=n;i++) {
			if(x[i]==1)
				System.out.print(i+" ");   //列印標記為1 的物品
		}
	}
	
		

	private static int max(int i, int j) {
		return i>j? i:j ;
	}

}

結果:


時間複雜度:主要是兩層巢狀 O(n*W)

空間複雜度:c[n][W]  O(n*W)

相關推薦

動態規劃-0-1揹包問題

給定n個物品和一個揹包。物品i的重量為wi,價值為vi,揹包容量為c。問如何選擇裝入揹包中的物品,使得裝入揹包的物品的價值最大?在裝入揹包時,每種物品i只有兩種選擇,裝入或者不裝入,既不能裝入多次,也不能只裝入一部分。 因此,此問題稱為0-1揹包問題.0-1揹包問題是一個特殊的整數規劃問題。

動態規劃 0-1 揹包問題 python

#有n 個物品,它們有各自的重量和價值,現有給定容量的揹包,如何讓揹包裡裝入的物品具有最大的價值總和? #number=4,capacity=8 在程式中用n表示物品數量,用j表示剩餘容量 w = [0,2,3,4,5]#表示重量 v = [0,3,4,5,6]#表示價值 #列出模型遞推式

動態規劃-0-1揹包

0-1揹包,動態規劃解決方案 三個物品, 考慮揹包能夠攜帶的重量只有5 。對於這個例子,我們可以說最佳解決方案是往揹包裡裝入 物品1 和物品2 ,這樣,總重量為5 ,總價值為7 。       function knapSack(capacity,

動態規劃--0-1揹包問題1

package com.duoduo.day316; /** * 0-1揹包問題 * * 問題描述:有n個物品,每個物品的重量為w[i], 價值為v[i],購物車容量為W,選擇若干個物品放入購物車 * 限制:在不超過容量的前提下使獲得的價值最大 * 思路:和之前的

動態規劃 0-1揹包問題

問題描述: 給定N種物品和一個揹包。物品i的重量是Wi,其價值位Vi ,揹包的容量為C。問應該如何選擇裝入揹包的物品,使得轉入揹包的物品的總價值為最大?? 在選擇物品的時候,對每種物品i只有兩種選擇,即裝入揹包或不裝入揹包。不能講物品i裝入多次,也不能只裝入物品的一部分。因

動態規劃01揹包問題

                                                                 動態規劃0-1揹包問題 Ø    問題描述:    給定n種物品和一揹包。物品i的重量是wi,其價值為vi,揹包的容量為C。問應如何選擇裝入揹包

動態規劃0-1揹包問題

Ø    問題描述:    給定n種物品和一揹包。物品i的重量是wi,其價值為vi,揹包的容量為C。問應如何選擇裝入揹包的物品,使得裝 入揹包中物品的總價值最大? Ø   對於一種物品,要麼裝入揹包,要麼不裝。所以對於一種物品的裝入狀態可以取0和1.我們設物品i的裝入狀態為

動態規劃0-1揹包問題

       演算法是對特定問題求解步驟的一種描述,或定義解決某問題的規則,演算法的設計和實現體現了計算機破解過程。演算法的設計也是一種思想和智慧的結晶,常用的演算法設計技術主要有分治法、動態規劃法、

動態規劃 0-1揹包問題

問題 給定n個物品和一揹包,物品i的重量是wi,其價值是vi,揹包的容量是m,問如何選擇裝入揹包中的物品總價值最大? 解答思路 a) 把揹包問題抽象化(X1,X2,…,Xn,其中 Xi 取0或1,表示第 i 個物品選或不選,類似指示器隨機變數),Vi表示第

動態規劃--0,1揹包問題(再也不怕類似揹包問題了)

這種型別問題三大要素:總重量、每件物品重量、每件物品價值,問最終能夠塞進揹包中的價值最大是多少?應該怎麼選擇物品? 當然也不一定是這些,例如上節所說的礦工挖礦:總人數、挖每座礦的人數、每座礦的金子數。 也就是說,只要出現了這三大要素,都可以視為0,1揹包問題(物品不可拆分) 動態規劃三要素:邊界、最優子結構、

揹包問題與動態規劃狀態轉移方程1

阿福是一名經驗豐富的大盜。趁著月黑風高,阿福打算今晚洗劫一條街上的店鋪。這條街上一共有 N 家店鋪,每家店中都有一些現金。阿福事先調查得知,只有當他同時洗劫了兩家相鄰的店鋪時,街上的報警系統才會啟動,然後警察就會蜂擁而至。作為一向謹慎作案的大盜,阿福不願意冒著被警察追捕的風險

動態規劃01--切鋼條(1)

# -*- coding: utf-8 -*- import random def getp(n): ''' 獲取一個長度為n的價格表 ''' p = [0 for i

動態規劃的基礎篇1--最大連續子序列和

上篇已經稍微介紹了什麼是dp,接下來就是實戰了。今天七夕節,祝願大家有人陪伴,好好珍惜。。哎。。 給定一個數字序列A1,A2,A3,A4,A5,A6,A7,A8,A9.....An。求i,j(1<=i<=j<=n)使得Ai++++++Ai最大,輸出這個最大

藍精靈算法進階——動態規劃背包(1

close span 數組 char font == nbsp 最大 view 我覺得我還是分好幾篇寫這個東西吧-嗷; PACK 還有一個網站背包模板都有;AcW 1.01背包 有 N 件物品和一個容量是 V 的背包。每件物品只能使用一次。 第 i 件物品的體積是

採藥-動態規劃(01揹包

採用一維陣列進行優化 #include<cstdio> #include<algorithm> using namespace std; int w[105], v[105]; int dp[1005]; int main() { int m, n; sca

POJ-2184 Cow Exhibition 【動態規劃DP+01揹包變換】

題目傳送門 題目:共有N頭牛,接下來N行是每頭牛的智商和情商,從這些牛中任意選取若干頭牛,使得牛的智商和+情商和最大,同時智商和(TS),情商和(TF)都不小於0。 題解:以智商作為容量,求前i頭牛在智商為j的情況下的最大情商 。因為有負數,所以容量擴大100000,修改dp陣

HDU-2844 Coins 【動態規劃DP+多重揹包

題目傳送門 題目:有n種硬幣,第i種硬幣的價值為Ai,數目為Ci,求這些硬幣能配出1~m中的幾種價值。 題解:dp[j]表示是否能配出價值j。sum[i][j]表示第i種硬幣取到價值j時需要的數目。sum陣列可以壓掉i的那一維,每次都要記得清零。 AC程式碼: #include

POJ-2392 Space Elevator 【動態規劃DP+多重揹包

題目傳送門 題目:牛要去太空了!他們計劃通過建造一種太空升降機來達到軌道:一個巨大的積木塔。他們有K (1 <= K <= 400)不同型別的積木來建造塔。型別i的每個塊的高度都是h_i (1 <= h_i <= 100),並且數量上都是c_i (1 <= c_

動態規劃之完全揹包問題(java實現)

之前寫了01揹包問題,現在寫完全揹包問題。和01揹包不同的是,完全揹包不限定某種物品的件數,可以裝0,1,2,...,而01揹包只有裝與不裝的區別。但是思考問題的方式還是一樣的,我就其中的最大值。詳細程式碼和註釋見下面程式碼。 package backpack; /* f[i][v]:前i件物

【leetcode】動態規劃之01揹包問題

先學會手動填動態規劃的表  後面的顏色塊值是根據前面的顏色塊值計算出來的,不懂就留言 #include<iostream> #include<vector> using namespace std; int Knapsack(vector<i