01背包优化
复习
含义:
//dp[i][j]:体积为j,前i件物品的最大价值
dp[i][0]表示没有体积的时候选择商品,结果为0
所以不用初始化
状态转移方程:
if(j>=w[i])dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);
else dp[i][j]=dp[i-1][j];
//小明的背包题解
#include<bits/stdc++.h>
using namespace std;
const int N=1e3+9;
int n,m,w[N],v[N],dp[N][N];//第i件商品,体积为V条件下的最大价值
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>w[i]>>v[i];
}
for(int i=1;i<=n;i++)//对于每一件物品
{
for(int j=1;j<=m;j++)
{
if(j>=w[i])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][m]<<endl;
return 0;
}
#include <bits/stdc++.h>
using namespace std;
int dp[1010][1010];
int v[1010],w[1010];//体积和价值
int main(){
int N,V;
int i,j;
cin>>N>>V;//商品个数和背包容量
for(i=1;i<=N;i++)
{
cin>>v[i]>>w[i];//体积和价值
}
//dp[i][j]表示在[1-i]个范围之内且体积为j的条件下能够获得的最大价值
for(int i=1;i<=N;i++)
{
for(int j=1;j<=V;j++)
{
if(j>=v[i]) dp[i][j]=max(dp[i-1][j],dp[i-1][j-v[i]]+w[i]);
else dp[i][j]=dp[i-1][j];//表示当前的容量无法将第i件物品装入
}
}
cout<<dp[N][V]<<endl;//输出前N个商品,背包容量为V的最优解
return 0;
}
考虑:当前物品放、不放
放:当前物品的价值+减去当前重量的背包放前i-1个物品的最大值
[轻松掌握动态规划]4.01背包_哔哩哔哩_bilibili
01背包不依赖物品的顺序:
每个物品只有选或不选,与顺序无关。
第一行0-8表示背包的容量
第一列0-4表示待选物品的种类数。
D[0][i]:表示对于任意容量的背包都不装东西,最大价值为0。
D[i][0]:表示对于任意物品的容量为0背包都装不进去,最大价值也为0;
过程:
#include<bits/stdc++.h>
using namespace std;
int dp[1010][1010]={};
int w[1010],v[1010];
int main()
{
int n,V;
cin>>n>>V;
//物品的体积和价值
for(int i=1;i<=n;i++)
{
cin>>w[i];
cin>>v[i];
}
//
for(int i=1;i<=n;i++)
{
for(int j=1;j<=V;j++)
{
if(w[i]>j) dp[i][j]=dp[i-1][j];
else dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);
}
}
cout<<dp[n][V];
return 0;
}