完全背包例题
题目描述
有 n 件物品和一个容量是 m 的背包。每件物品都可以使用无数次。
第 i 件物品的体积是 vi,价值是 wi。
求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。输出最大价值。
输入描述
第一行两个整数,n,m,用空格隔开,分别表示物品数量和背包容积。
接下来有 n 行,每行两个整数 vi,wi,用空格隔开,分别表示第 i 件物品的体积和价值。
0<n,m≤1000
0<vi,wi≤1000
输出描述
输出一个整数,表示最大价值。
样例输入 1
4 5 1 2 2 4 3 4 4 5
样例输出 1
10
完全背包问题和01背包问题很相似。
01背包问题每个物品只能选一个,而完全背包问题每个物品可以选无限次。
DP问题的关键是找到状态转移方程:
1.状态函数f[i][j]表示第i件物品容量为j最大价值
2.f[i][j]=max(f[i-1][j],f[i][j-w[i]]+v[i]);装得下分为两种情况1.装 2.不装 同时注意是与f[i][j-w[i]]+v[i]比较而不是i
一.二维代码
#include <bits/stdc++.h>
using namespace std;
int f[100][100];//状态函数f[i][j]表示第i件物品容量为j最大价值
int v[100];
int w[100];
/*
函数功能:求完全背包
函数形参:物品数量和背包容量
函数返回值:返回最大值
*/
int fun(int n,int m)
{
for(int i=1;i<=n;i++) //物品
{
for(int j=1;j<=m;j++) //容量
{
if(j<w[i]) //装不下
f[i][j]=f[i-1][j]; //就等于i-1件物品容量等于j时候的价值
else
f[i][j]=max(f[i-1][j],f[i][j-w[i]]+v[i]);//装得下分为两种情况1.装 2.不装 同时注意是与f[i][j-w[i]]+v[i]比较而不是i
}
}
return f[n][m];
}
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>w[i]>>v[i];
cout<<fun(n,m);
system("pause");
return 0;
}
二.一维优化代码
#include <iostream>
using namespace std;
const int N=1010;
int v[N],w[N],f[N];
int n,m;
int main()
{
scanf("%d%d",&n,&m);
for(int i = 1;i <= n;i++){
scanf("%d%d",&v[i],&w[i]);
}
for(int i=1;i<=n;i++)
for(int j=v[i];j<=m;j++){
f[j]=max(f[j],f[j-v[i]]+w[i]);//一维优化之后与01背包优化类似
}
printf("%d",f[m]);
return 0;
}
解决完全背包!
关注我,带你入坑下一个多重背包!