背包问题
- 挑东西的问题
01背包_选与不选的问题
- 循环变量从大到小,避免重复(否则将变成完全背包)
- f[N]表示的是在N的资源下达成的结果,这里的N的资源并不是处在all in的状态,而是可以允许闲置的状态。
- 当前的状态从何而来?一般是消耗一定的资源来换取一定的成果。
- 有些题目存在开启条件,如278. 数字组合,所有的数字起源都来自于0,要令f[0]=1,从而通过f[0]=1来初始化其他的数字
1024.装箱问题
有一个箱子容量为 V,同时有 n 个物品,每个物品有一个体积(正整数)。
要求 n 个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。
- 尽可能拉大体积
#include<bits/stdc++.h>
using namespace std;
int main()
{
int V;
int n;
cin>>V>>n;
int f[V+1],v;
memset(f,0,sizeof(f));
for(int i=1;i<=n;i++)
{
cin>>v;
for(int j=V;j>=v;j--)
{
f[j]=max(f[j],f[j-v]+v);
}
}
cout<<V-f[V];
return 0;
}
278. 数字组合
给定 N个正整数 A1,A2,…,AN,从中选出若干个数,使它们的和为 M,求有多少种选择方案。
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,m;
cin>>n>>m;
int f[m+1];
memset(f,0,sizeof(f));
f[0]=1;
for(int i=0;i<n;i++)
{
int x;
cin>>x;
for(int j=m;j>=x;j--)
f[j]=f[j]+f[j-x];
}
cout<<f[m];
return 0;
}
完全背包_选多和选少的问题
二维费用的背包问题_站在01背包的肩上
- 由
f[状态类型1]
变成f[状态类型1][状态类型2]
8. 二维费用的背包问题
#include<bits/stdc++.h>
using namespace std;
const int N = 1e3+10;
int main()
{
int N,VOL,WEI;
cin>>N>>VOL>>WEI;
int vol,wei,val;
int f[VOL+1][WEI+1];
memset(f,0,sizeof(f));
for(int i=0;i<N;i++)
{
cin>>vol>>wei>>val;
for(int j=VOL;j>=vol;j--)
for(int k=WEI;k>=wei;k--)
{
f[j][k]=max(f[j][k],f[j-vol][k-wei]+val);
}
}
cout<<f[VOL][WEI]<<endl;
return 0;
}
其他
并查集加背包
#include<bits/stdc++.h>
using namespace std;
const int N = 1e4+10;
int f[N];
struct article{
int money;
int val;
}a[N];
int find(int x)
{
if(f[x]==x) return x;
else return f[x] = find(f[x]);
}
int main()
{
int n,m,w;
cin>>n>>m>>w;
map<int,article > counter;
for(int i=1;i<=n;i++)
{
cin>>a[i].money>>a[i].val;
f[i] = i;
}
for(int i=0;i<m;i++)
{
int c1,c2;
cin>>c1>>c2;
int f1=find(c1),f2=find(c2);
if(f1!=f2)
f[f1]=f2;
}
map <int ,int > fpos;
int cost[n+1],value[n+1],f[w+1],cnt=0;
memset(f,0,sizeof(f));
for(int i=1;i<=n;i++)
{
int ffa=find(i);
if(fpos.count(ffa)==0)
fpos[ffa]=cnt,cost[cnt]=a[i].money,value[cnt]=a[i].val,cnt++;
else cost[fpos[ffa]]+=a[i].money,value[fpos[ffa]]+=a[i].val;
}
for(int i=0;i<cnt;i++)
{
for(int j=w;j>=cost[i];j--)
f[j]=max(f[j-cost[i]]+value[i],f[j]);
}
cout<<f[w];
return 0;
}