10月15日
#include<iostream>
using namespace std;
const int N=1010;
int f[N][N];
int v[N],w[N];
int n,m;
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>v[i]>>w[i];
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
f[i][j]=f[i-1][j];
if(j>=v[i])
f[i][j]=max(f[i-1][j],f[i-1][j-v[i]]+w[i]);
}
cout<<f[n][m]<<endl;
return 0;
}
状态属性:f[i][j]表示在在前i个物品中j的体积下最大的重量是多少
状态方程的解释:01背包有两种状态。第一种为前i种第i个物品的不取状态,所以则f[i][j]=f[i-1][j],显然不取则两者状态相同,第i个物品不取是因为此时不能取(v[i]>j)无法取。第二种为前i种物品中第i个品物取的状态(v[i]<=j),所以取f[i-1][j-v[i]]+w[i]和f[i-1][j]的最大值
//01背包一维的优化
#include<iostream>
using namespace std;
const int N=1010;
int f[N];
int v[N],w[N];
int n,m;
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>v[i]>>w[i];
for(int i=1;i<=n;i++)
for(int j=m;j>=v[i];j--)
{
f[j]=max(f[j],f[j-v[i]]+w[i]);
}
cout<<f[m]<<endl;
return 0;
}
优化过程即为为状态转移方程的等价
一维优化顾名思义,去掉一个维度,那么我们删掉f[i][j]中[i]的维度 。为什么j的枚举从m开始向后枚举而不是从v[i]开始向前枚举呢?如果此时我们从v[i]枚举,我们可能会使用到本应该在i-1中的状态而却用在了i状态下,简而言之因为我们去掉一个维度我们并不知道此时v[i]时f[i-1][j]还是f[i][j]下的体积。