题目描述:
有为N件物品,它们的重量w分别是w1,w2,…,wn,它们的价值v分别是v1,v2,…,vn,每件物品数量有且仅有一个,现在给你个承重为M的背包,求背包里装入的物品具有的价值最大总和?
输入:
第一行输入物品个数n和背包容量m
第二行输入每个物品的重量
第三行是输入每个物品的价值
输出:
物品个数n背包容量为m的最大价值
示例:
输入
6 10
2 5 4 7 9 3
2 4 9 3 4 7
输出
18
分析:
dp数组定义
dp[i][j]表示有i个物品背包容量为j的时候的最大价值
推导公式
如果能放下物品i,dp[i][j] = max(dp[i-1][j],dp[i-1][j-zhong[i]] + value[i])
如果放不下物品i,dp[i][j] = dp[i-1][j]
初始化数组
判断zhong[1]是否大于j,将dp[1][j]进行初始化
代码:
int Knapsack()
{
/处理输入数据,用合适的容器存储
int n;
int m;
std::cin>>n;
std::cin>>m;
int *zhong = new int[n+1];
int *value = new int[n+1];
int k = n;
int i = 1;
while(k--)
{
int ZL;
std::cin>>ZL;
zhong[i++] = ZL;
}
int h = n;
int j = 1;
while(h--)
{
int VL;
std::cin>>VL;
value[j++] = VL;
}
vector<vector<int>> dp(n+1,vector<int>(m+1,0));
初始化第一行
for(int i=1;i <= m;i++)
{
if(zhong[1] <= i)
dp[1][i] = value[1];
}
一行一行的填充dp数组
for(int i = 2;i <= n;i++)
{
for(int j = 1;j <= m;j++) ///背包重量从1加到m
{
if(zhong[i] > j)
{
dp[i][j] = dp[i-1][j];
}
else
{
dp[i][j] = max(dp[i-1][j],dp[i-1][j-zhong[i]] + value[i]);
}
}
}
///将dp数组打印出来
for(int i=0;i<=n;i++)
{
for(int j=0;j<=m;j++)
{
cout<<dp[i][j]<<" ";
}
cout<<endl;
}
free(zhong);
free(value);
return dp[n][m];
}
int main()
{
cout<<Knapsack()<<endl;
}
运行结果: