01背包问题
状态表示:\(f(i,j):\)从前\(i\)个物品中选,总体积不超过\(j\)的情况下的最大价值
(蓝书上定义的是总体积为\(j\)的最大价值,初始化时要作出相应的修改)
状态转移:
- 选第\(i\)个物品:\(f(i,j)=f(i-1,j-v_i)+w_i\)
- 不选第\(i\)个物品:\(f(i,j)=f(i-1,j)\)
const int N=1010;
int f[N][N];
int n,m;
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
int v,w;
cin>>v>>w;
for(int j=0;j<=m;j++)
if(j<v) f[i][j]=f[i-1][j];
else f[i][j]=max(f[i-1][j],f[i-1][j-v]+w);
}
cout<<f[n][m]<<endl;
//system("pause");
}
第\(i\)层状态只与第\(i-1\)层状态有关,采用滚动数组优化
const int N=1010;
int f[2][N];
int n,m;
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
int v,w;
cin>>v>>w;
for(int j=0;j<=m;j++)
if(j<v) f[i&1][j]=f[i-1&1][j];
else f[i&1][j]=max(f[i-1&1][j],f[i-1&1][j-v]+w);
}
cout<<f[n&1][m]<<endl;
//system("pause");
}
可继续优化至一维:
const int N=1010;
int f[N];
int n,m;
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
int v,w;
cin>>v>>w;
for(int j=m;j>=v;j--)
f[j]=max(f[j],f[j-v]+w);
}
cout<<f[m]<<endl;
//system("pause");
}