0-1揹包問題(Dynamic Programming)

如果揹包的體積爲C,物品的個數爲N,則算法複雜度爲 O(n) = C * N 。

解決思路:

每次嘗試往揹包裏新加一個物品,如果裝不下,則將體積組建增大。當能裝下時候,用當前體積減去新裝入的這個物品的體積,得到除了當前這個物品的體積,在之前的已知解中查找這個體積容納的最大價值,用這個最大價值加上當前物品的價值就是新的最大價值。

#include<iostream>
#include<stdio.h>
using namespace std;
 
void Knapsack(int n,int c,int *w,int *p){
    int f[100][100];
	int i=0,j=0;
	for(i=1;i<=n;i++){  # n 是物品的個數,這一層循環嘗試逐個添加物品
		for(j=1;j<=c;j++){  # j是當前體積,逐漸增加體積 ,觀察體積變大後放入當前物品j之後價值的變化
			f[i][j]=f[i-1][j]; # i-1 是上一個物品, [j] 當前體積,f[i-1][j] 也就是上一個物品當前體積下的最大價值
			if(j>=w[i]){  # j 是當前體積, w[i] 是當前物品的體積,因爲要往揹包裏放入當前物品,所以當前假定的體積要大於物品的體積
				f[i][j]=max(f[i-1][j],f[i-1][j-w[i]]+p[i]);  # 如果能放下,要查找除掉當前物品的體積之後的體積能裝的最大的價值, f[i-1][*] 是添加上一個物品的已知解空間, 
                # w[i] 是當前物品的體積, j 是當前假設揹包的體積 j-[w[i]] 也就是當前揹包的體積去掉當前物品的體積, f[i-1][j-w[i]] 就是去掉當前物品體積後還剩下的體積裝的最大價值
                # f[i-1][j-w[i]]+p[i] 即是裝上當前物品後的最大價值
                # f[i-1][j] 是不轉入當前物品的最大價值,一般不會取這個值,除非有物品價值爲負數或者0
			}
		}
	}

	cout<<"揹包能裝的最大價值是:" << f[i-1][j-1] <<endl;
}
int main(){
    int n;
    int c;
    
    c=10;   //揹包容量c
    n=5;    //物體個數n
    int w[6]={0,2,2,6,5,4};   //物品體積
    int p[6]={0,6,3,5,4,6};   //物品價值
    Knapsack(n,c,w,p);

}

參考:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章