#include<iostream>
using namespace std;
/*const int N=1010;
int f[N][N];
int n,m;
int v[N],w[N];
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][j],f[i-1][j-v[i]]+w[i]); //其实二维数组开得太大,而且很多数据我们根本用不上.
}
int res=0;
for(int i=1;i<=m;i++)res=max(res,f[n][i]);
cout<<res;
return 0;
}*/
/*
const int N=1010;
int f[2][N];
int n,m;
int v[N],w[N];
int main()//滚动数组
{
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>v[i]>>w[i];
for(int i=1;i<=n;i++)//滚动数组,当前行和前一行数据对转移方程有用所以开个[2][N]就够了
for(int j=1;j<=m;j++)//我对它不熟悉只能推理一下看法,最终的结果就在转移的这矩阵里面找,因为i是可能最后滚到0或者1跟n的值有关
{
f[i%2][j]=f[(i-1)%2][j];//所以最后搜索要全遍历,= =如果推理错了请大佬指出来我修改。
if(j>=v[i])
f[i%2][j]=max(f[i%2][j],f[(i-1)%2][j-v[i]]+w[i]);
}
int res=0;
for(int i=0;i<2;i++)
for(int j=1;j<=m;j++)
res=max(res,f[i][j]);
cout<<res;
return 0;
}*/
const int N=1010;
int f[N];
int n,m;
int v[N],w[N];
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]); //降为的话我们不仅空间压缩了,其实还剪枝了,像二维那些奇葩的[i][0],[i][1]数据给的体积比它大
//这里通过j>=v[i]我们可以特判掉很多无用计算,保证计算的都是有效数据
//然后思想其实还是根据二维数组演变来的,
cout<<f[m]; // f[j]=max(f[j],f[j-v[i]]+w[i])等价==》f[i][j]=max(f[i-1][j],f[[i-1][j-v[i]]+w[i])
//就当我们循环到i=2的时候此时我们数组的值全是i=1的值,此时只要我们从最大体积开始循环
//就不会影响我们计算max(f[i-1][j],f[[i-1][j-v[i]]+w[i])如果体积是升序那我们算到后面都会
//用i=2的当前层的值,然后通过转移我们可以得出f[m],这里的f[m]意义是体积<=m可以获得的最大价值;
//如果题目给到m-1体积就能达到最大价值,那么f[m-1]和f[m]都是答案,
//但是我们不确定体积用了多少就能达到最大价值,所以这个f[m]相当于通解。
return 0;
}
0-1背包问题(二维,滚动数组,一维)(c++)
最新推荐文章于 2024-04-25 23:15:19 发布