背包问题借助打表记录,不断扩大每个子背包,记录最大价值直到整个背包,VM[i][j]为第i件商品,背包容量为j的情况下的最优价值,第i件商品的最优价值分两种情况,拿i的话价值为(出去i的重量时的最大价值+i的价值),不拿的话最大价值为i-1时的最大价值。两种情况取价值最大的,当i=n,j=m时即为此背包的价值最大。
#include <bits/stdc++.h>
using namespace std;
int Wight[100],Value[100];
int VM[100][200];//VM:value Max,层数代表商品序号,列代表背包当前容量,数值代表此容量下的最大价值。
int main()
{
int n,m;//n件商品,m背包容量。
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>Wight[i]>>Value[i];
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(j<Wight[i]) VM[i][j]=VM[i-1][j];//当背包不足以放下商品i时,最优价值与i-1时相同。
else VM[i][j]=max(VM[i-1][j],VM[i-1][j-Wight[i]]+Value[i]);//背包可以放下i时,价值=max【(i的价值+减去i重量时的最优价值),不拿i的最优价值】
//检验程序,横坐标为背包容量0~m,纵坐标为商品0~n.
for(int i=0;i<=n;i++)
{
for(int j=0;j<=m;j++)
cout<<VM[i][j]<<" ";
cout<<endl;
}
cout<<"最大价值 :";
cout<<VM[n][m];
}
使用循环数组,节省空间
#include <bits/stdc++.h>
using namespace std;
int Wight[100],Value[100],VM[200];
int main()
{
int n,m;//n件商品,m背包容量。
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>Wight[i]>>Value[i];
for(int i=1;i<=n;i++)
for(int j=m;j>=1;j--)
if(j>=Wight[i]) VM[j]=max(VM[j],VM[j-Wight[i]]+Value[i]);//背包可以放下i时,价值=max【(i的价值+减去i重量时的最优价值),不拿i的最优价值】
cout<<VM[m];
}