如果揹包的體積爲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);
}
參考: