1.最简单的一个,01背包与完全背包,我只讲一维的,二维的很好理解。
https://www.luogu.org/problemnew/show/P1060
#include<bits/stdc++.h>
using namespace std;
const int maxn=3e4+10;
int w[30],v[30];
int dp[maxn];
int main()
{
int n,m;
scanf("%d %d",&n,&m);
for(int i=0;i<m;i++)
{
scanf("%d %d",&v[i],&w[i]);//读入背包
w[i]*=v[i];//读入价值
for(int j=n;j>=v[i];j--)//体积从大到小!!这里一定是这样
//若从小到大的话,那么同一个物品就能备选两次例如一个dp[500]=dp[500-300]+200;
//那么500这个体积的背包已经取了物品一次,那么后面dp[800]=dp[800-300]+200;
//这里又会再取一次,很显然,这就是完全背包,这里一并讲了
dp[j]=max(dp[j],dp[j-v[i]]+w[i]);//max函数里面的d[j]其实储存的是d[i-1][j]
//因为很显然,我是一个物品一个物品选择的,那么我对等号前面的dp[j]没操作时储存的
//肯定是i-1的值
}
cout<<dp[n]<<endl;
}
完全背包代码
例题:https://www.luogu.org/problemnew/show/P1616
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int f[maxn];
int main()
{
int n,m;
scanf("%d %d",&n,&m);
for(int i=0;i<m;i++)
{
int w,v;
scanf("%d %d",&w,&v);
for(int i=w;i<=n;i++)
f[i]=max(f[i],f[i-w]+v);
}
cout<<f[n]<<endl;
}