01背包
例:洛谷2871.手链
有N件物品和一个容量为V的背包。第i件物品的重量是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的重量总和不超过背包容量,且价值总和最大。
解:
#include<iostream>
#include<stdlib.h>
using namespace std;
int f[100001],v[100001],w[100001];
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>w[i]>>v[i];
for(int i=1;i<=n;i++)
for(int j=m;j>=w[i];j--)//由于f[i][j]只跟f[i-1][j]与f[i-1][j-w[i]]+v[i]有关
//故可采用一位数组滚动的方式,又由于f[j]可能跟f[j-w[i]]有关 故第二个循环倒序(每种东西只有一个)
f[j]=max(f[j],f[j-w[i]]+v[i]);
cout<<f[m];
system("pause");
return 0;
}
完全背包
例:洛谷2722.总分
有N种物品(每种物品无限个)和一个容量为V的背包。第i件物品的重量是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的重量总和不超过背包容量,且价值总和最大。
解:
#include<iostream>
#include<stdlib.h>
using namespace std;
int f[100001],v[100001],w[100001];
int main()
{
int n,m;
cin>>m>>n;
for(int i=1;i<=n;i++) cin>>v[i]>>w[i];
for(int i=1;i<=n;i++)
for(int j=w[i];j<=m;j++)//由于f[i][j]只跟f[i-1][j]与f[i-1][j-w[i]]+v[i]有关
//故可采用一位数组滚动的方式,又由于每件东西可以无限取
//故采用正序(f[j]可由之前已取过一件该物品的最优状态更新)
f[j]=max(f[j],f[j-w[i]]+v[i]);
cout<<f[m];
system("pause");
return 0;
}