题目描述: 有编号分别为a,b,c,d,e的五件物品,它们的重量分别是2,2,6,5,4,它们的价值分别是6,3,5,4,6,现在给你个承重为10的背包,如何让背包里装入的物品具有最大的价值总和?
根据m[i][j]的递推公式,背包中最大的价值总和为m[1][n]
#include <iostream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
int main()
{
int n;//一共有n个物品
int weight;//背包承重为weight
cin>>n>>weight;
int w[n+1];//用来表示每个物品的重量
int v[n+1];//用来表示每个物品的价值
for(int i=1;i<=n;i++)
cin>>w[i]>>v[i];
int m[n+1][weight+1];
//当背包容量为0时,背包能容纳的最大价值量为0
for(int i=0;i<=n;i++)
m[i][0]=0;
//初始条件,最后一行
//如果背包装不下第n个物品,m[n][j]=0
//如果背包能够装下第n个物品,m[n][j]=v[n]
for(int j=0;j<=weight;j++){
if(j<w[n])
m[n][j]=0;
else
m[n][j]=v[n];
}
//逆序填充二维数组m[i][j]
for(int i=n-1;i>=1;i--)
for(int j=1;j<=weight;j++)
{
if(j<w[i])
//如果装不下当前物品,即不装当前物品,有m[i][j]=m[i+1][j]
m[i][j]=m[i+1][j];
else{
//能够装下当前物品,比较装下后剩余背包容量所能容纳最大价值量与当前物品价值量之和
//与不装当前物品的背包容纳最大价值量之和
if(m[i+1][j]>m[i+1][j-w[i]]+v[i])
m[i][j]=m[i+1][j];
else
m[i][j]=m[i+1][j-w[i]]+v[i];
}
}
//m[1][weight]即为最优解
cout<<m[1][weight];
return 0;
}
时间复杂度
算法复杂度分析:
从m(i,j)的递归式容易看出,算法需要O(nweight)计算时间。当背包容量weight很大时,算法需要的计算时间较多。例如,当weight>2n时,算法需要Ω(n2n)计算时间