01背包问题情境:
有n件物品,每件物品的重量为w[i],价值为c[i],现有一个容量为V的背包,问如何选取物品放入背包,使得背包内物品的总价值量最大,其中每种物品都只有一件
核心代码:(要注意这里是逆序枚举的)
for(int i = 1;i <= n;i++){
for(int v = V;v >= w[i];v--){
//状态转移方程
dp[v] = max(dp[v],dp[v-w[i]] + c[i]);
}
}
完整代码:
#include <stdio.h>
#include <algorithm>
using namespace std;
const int maxn = 100; //物品最大件数
const int maxv = 1000; //V的上限
int w[maxn],c[maxn],dp[maxv]; //w为物品重量,c为价值量容量 ,dp就是临时记录的一维数组
int main(){
int n,V;
scanf("%d%d",&n,&V);
for(int i = 1;i <= n;i++){
scanf("%d",&w[i]);
}
for(int i = 1;i <= n;i++){
scanf("%d",&c[i]);
}
//边界
for(int v = 0;v <= V;v++){
dp[v] = 0;
}
//以下开始为背包问题模板
for(int i = 1;i <= n;i++){
for(int v = V;v >= w[i];v--){
//状态转移方程
dp[v] = max(dp[v],dp[v-w[i]] + c[i]);
}
}
//寻找dp[0...V]中最大的即为答案
int max = 0;
for(int v = 0;v <= V;v++){
if(dp[v]>max){
max = dp[v];
}
}
printf("%d\n",max);
return 0;
}
/*
5 8
3 5 1 2 2
4 5 2 1 3
*/
附上样例:
问题 1100: 采药
https://www.dotcpp.com/oj/problem1100.html?sid=1898870&lang=1#editor
AC代码:
#include <stdio.h>
#include <algorithm>
using namespace std;
int a[10005];
int w[10005];
int f[1000005];
int main()
{
int t,m;
scanf("%d %d",&t,&m);
for(int b = 1; b <= m; b ++){
scanf("%d %d",&a[b],&w[b]);
}
for(int b = 1; b <= m; b ++){
for(int c = t; c >= a[b]; c--){
f[c]=max(f[c],f[c-a[b]]+w[b]);
}
}
f[0] = 0;
for(int b = 1; b<=t; b ++){
f[0]=max(f[0],f[b]);
}
printf("%d",f[0]);
return 0;
}
/*
70 3
71 100
69 1
1 2
*/