蒜头君去超市购物,他有一只容量为 VV 的购物袋,同时他想买 nn 件物品,已知每件物品的体积 v_ivi 和重要度 p_ipi。蒜头君想知道,挑选哪些物品放入购物袋中,可以使得买到的物品重要度之和最大,且物品体积和不超过购物袋的容量。
输入格式
第一行输入两个整数 VV(1 \leq V \leq 10001≤V≤1000)和 nn(1 \leq n \leq 1001≤n≤100)。代表购物袋的总体积为 VV,蒜头君一共想买 nn 件物品。
接下来输入 nn 行,每行输入两个整数 v_ivi 和 p_ipi(1 \leq v_i, p_i \leq 1001≤vi,pi≤100),分别表示每件物品的体积和重要度。
输出格式
输出一行,输出一个整数,表示蒜头君能买到物品的最大重要度之和。
样例输入
50 4 1 5 60 99 49 8 33 7
样例输出
13
动态规划经典题目 每一种决策只有选择或者不选两种状态 所以叫做0-1背包问题
我对其的理解就是空间换时间 每次将需要的值存储 下一次直接调用即可
0-1背包 如果该物品的体积满足最大存放体积 则其等于 dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);
dp[i-1][j] 代表第i项不取 dp[i-1][j-w[i]]+v[i]代表取了第i项
如果不满足存放则dp[i][j]=dp[i-1][j];
AC代码:
#include <bits/stdc++.h>
#include <memory.h>
using namespace std;
int main()
{
int V,n,dp[110][1010],v[110],w[110];//dp[i][j] 代表前i项 总重量不超j的最大取值;
memset(dp,0,sizeof(dp));
cin>>V>>n;
for(int i=1;i<=n;i++)
cin>>w[i]>>v[i];
for(int i=1;i<=n;i++)
{
for(int j=0;j<=V;j++)
{
if(w[i]<=j)//表示当前第i项的体积小于j 即可以放入背包
dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);
else
dp[i][j]=dp[i-1][j];
}
}
cout<<dp[n][V];
return 0;
}
当然 空间复杂度还可以进一步优化 只用以为数组存储;
AC代码:
#include <bits/stdc++.h>
#include <memory.h>
using namespace std;
int main()
{
int n,V,dp[1010],w[110],v[110];
cin>>V>>n;
for(int i=1;i<=n;i++)
cin>>w[i]>>v[i];
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++)
{
for(int j=V;j>=w[i];j--)
dp[j]=max(dp[j-w[i]]+v[i],dp[j]);
}
cout<<dp[V];
return 0;
}