23/3/6学习记录(背包九讲!)
1. 01背包问题
有 N 件物品和一个容量为 V 的背包,每件物品有各自的价值且只能被选择一次,要求在有限的背包容量下,装入的物品总价值最大。
方程:f [ i ][ j ] = max( f [ i -1 ][ j ] , f [ i -1 ][ j - v[ i ] ] + w[ i ] )
#include <stdio.h>
int max(int a,int b)
{
return a>b?a:b;
}
const int N=1010;
int f[N][N];
int v[N],w[N];
int n,m;
int main()
{
scanf("%d %d",&n,&m)
for(int i=1;i<=n;i++)
scnaf("%d %d",&v[i],&w[i]);
for(int i=1;i<=n;i++)//i从1开始,变量已经初始化为0
{
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=f[n][m];
return 0;
}
/*如果是一维数组优化则是
for(int i=0;i<=n;i++)
for(int j = m; j >= v[i]; j--)
f[j]=max(f[j],f[j-v[i]] + w[i])
int res=f[m];
*/
2. 完全背包问题
有 N 件物品和一个容量为 V 的背包,每件物品可以被选无数次,要求在有限的背包容量下,装入的物品总价值最大。
方程:f [ i ][ j ] = max( f [ i -1 ][ j ] , f [ i ][ j - v[ i ] ] + w[ i ] )
#include <stdio.h>
int max(int a,int b)
{
return a>b?a:b;
}
const int N=1010;
int f[N][N];
int v[N],w[N];
int n,m;
int main()
{
scanf("%d %d",&n,&m)
for(int i=1;i<=n;i++)
scnaf("%d %d",&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][j-v[i]]+w[i]);
}
}
int res=f[n][m];
return 0;
}
/*一维数组优化
for(int i=0;i<=n;i++)
for(int j = v[i]; j <= m; j++)
f[j]=max(f[j],f[j-v[i]] + w[i])
int res=f[m];
*/
3. 多重背包问题
有 N 件物品和一个容量为 V 的背包,第 i 种物品最多有 si 件,每件体积是vi,价值是 wi ,要求在有限的背包容量下,可将那些物品装入使装入的物品总价值最大,输出最大价值。
方程:f [ j ]=max{ f [ j ], f [ j - v [ i ] ] + w[ i ], f [ j - 2*v [ i ] ], ... }
/*
f[i]是总体积为i的情况下,最大价值
for(int i=0;i<n;i++)
{
for(int j=m;j>=v[i];j--)
f [ j ]=max( f [ j ], f [ j - v [ i ] ] + w[ i ], f [ j - 2*v [ i ] ], ... )
}
*/
#include <stdio.h>
const int N=110;
int n,m;
int f[N];
int main()
{
scanf("%d %d",&n,&m);
for(int i=0;i<n;i++)
{
int v,w,s;
scanf("%d %d %d",&v,&w,&s);
for(int j=m;j>=0;j--)
for(int k=1;k<=s&&k*v<=j;k++)
f[j]=max(f[j],f[j-k*v]+k*w]);
}
int res=f[m];
return 0;
}
4. 混合背包问题
5. 二维费用背包问题
6. 分组背包问题
7. 背包问题求方案数
8. 求背包问题的方案
9. 有依赖的背包问题
c编程学习记录 文章被收录于专栏
为了华为od机试刷题学习记录
CVTE公司福利 672人发布