目录
一. 问题描述
二. 题解及代码
一. 问题描述
背包问题(Knapsack problem)是一种组合优化的NP完全问题(NP完全问题,是世界七大数学难题之一)。
背包问题可以描述为:给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高。问题的名称来源于如何选择最合适的物品放置于给定背包中。根据条件不同,其具体可以分为01背包(基础背包)、完全背包、多重背包、分组背包等不同类型的问题,具体可以搜索背包九讲。
01背包也称为基础背包,是最基本的背包问题,说的是一共有 N 件物品(每件物品仅有一件),第 i(i从1开始)件物品的重量为w[i],价值为v[i]。在总重量不超过背包承载上限W的情况下,求能够装入背包的最大价值是多少?并输出具体选择的哪个物品?
二. 题解及代码
使用二维数组 dp[i][j] 表示从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和最大是多少。每件物品只有两种选择即放或不放,放入的话就要判断总价值是否会更大,其递推公式及参考代码如下:
dp[i][j] = Max( dp[i-1][j] ,dp[i-1][ j-wᵢ ]+vᵢ )
#include <stdio.h>
#include<string.h>int backpack[1000][1000];
int wi[1000];
int value[1000];
int x[1000];int main()
{int t;scanf("%d",&t);while(t--){int n,j,i,C;scanf("%d%d",&n,&C);for(i=1;i<=n;i++)scanf("%d",&wi[i]);for(i=1;i<=n;i++)scanf("%d",&value[i]);memset(backpack,0,sizeof(backpack));for(i=n;i>=1;i--){for(j=0;j<=C;j++){if(j<wi[i])backpack[i][j]=backpack[i+1][j];elsebackpack[i][j]=backpack[i+1][j]>(backpack[i+1][j-wi[i]]+value[i])?backpack[i+1][j]:backpack[i+1][j-wi[i]]+value[i];}}printf("最大值是:%d\n",backpack[1][C]);//二维数组倒推输出具体选择物品信息j=C;for(i=1;i<n;i++){if(backpack[i][j]==backpack[i+1][j])x[i]=0;else{j=j-wi[i];x[i]=1;}}if(backpack[n][j]==0)x[n]=0;else x[n]=1;for(i=1;i<=n;i++){if(x[i]!=0)printf("%d ",i);}printf("\n");}return 0;
}