01背包
01背包典型代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+1;
#define first fi
#define second se
typedef long long ll;
typedef pair<int,int> llp;
int w[N],v[N];//重量,价值
int a[N];
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--)
a[j]=max(a[j],a[j-w[i]]+v[i]);
}
cout<<a[m];
}
【01背包问题看这个视频就够了 01背包的2种解法详解 均含手动推导过程 干货满满】https://www.bilibili.com/video/BV1zz4y1q7jQ?vd_source=928e7968871dbf10f26b1952d35eabfa
可以看这个。注意二层循环要倒序
详情看这个解释。
那么如果不倒序,则就是多重背包
完全背包
完全背包,即每个物品可以拿无数次
完全背包典型代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+1;
const int M=1e7+1;
#define first fi
#define second se
typedef long long ll;
typedef pair<int,int> llp;
int w[N],v[N];//重量,价值
int a[M];
int main()
{
int n,m;
cin>>m>>n;
for(int i=1;i<=n;i++)
{
cin>>w[i]>>v[i];
}
for(int i=1;i<=n;i++)
{
for(int j=w[i];j<=m;j++)
a[j]=max(a[j],a[j-w[i]]+v[i]);
}
cout<<a[m];
return 0;
}
还要注意bp数组的最大值一般为M
而v,w数组的最大值为N
例题
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+1;
const int M=1e5+1;
typedef long long ll;
typedef long long ll;
typedef pair<int,int> llp;
llp a[M];
ll b[M],ans;
ll sum=0;
bool cmp(llp x,llp y)
{
return x.first+x.second<y.first+y.second;
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i].first>>a[i].second;
sum+=a[i].first;
}
sort(a+1,a+n+1,cmp);
for(int i=1;i<=n;i++)
{
for(int j=sum;j>=a[i].first;j--){
if(j-a[i].first<=a[i].second)b[j]=max(b[j],b[j-a[i].first]+a[i].second);
ans=max(ans,b[j]);}
}
cout<<ans;
return 0;
}
蓝桥的题