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

}

参考:

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