1.01背包
#include <cstdio>
#include <stack>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
#include <map>
#include <vector>
#include <queue>
#include <set>
#define eps 1e-8
typedef long long ll;
const double PI = acos(-1.0);
const int maxn = 1e6;
const int INF = 0x3f3f3f;
const ll linf = 0x3f3f3f3f3f3f3f3f;
using namespace std;
int f[maxn];
int v[maxn],w[maxn];
int n,V;
int main()
{
cin>>n>>V;
for(int i = 1; i<=n; i++)
cin>>v[i]>>w[i];
f[0] = 0;
for(int i = 1; i<=n; i++)
for(int j = V; j>=v[i]; j--)
f[j] = max(f[j],f[j-v[i]]+w[i]);
cout<<f[V]<<endl;
return 0;
}
2.完全背包
#include <cstdio>
#include <stack>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
#include <map>
#include <vector>
#include <queue>
#include <set>
#define eps 1e-8
typedef long long ll;
const double PI = acos(-1.0);
const int maxn = 1e6;
const int INF = 0x3f3f3f;
const ll linf = 0x3f3f3f3f3f3f3f3f;
using namespace std;
int f[maxn];
int v[maxn],w[maxn];
int n,V;
int main()
{
cin>>n>>V;
for(int i = 1; i<=n; i++)
cin>>v[i]>>w[i];
f[0] = 0;
for(int i = 1; i<=n; i++)
for(int j = v[i]; j<=V; j++)
f[j] = max(f[j],f[j-v[i]]+w[i]);
cout<<f[V]<<endl;
return 0;
}
3.多重背包
二进制拆分
#include <cstdio>
#include <stack>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
#include <map>
#include <vector>
#include <queue>
#include <set>
#define eps 1e-8
typedef long long ll;
const double PI = acos(-1.0);
const int maxn = 1e6;
const int INF = 0x3f3f3f;
const ll linf = 0x3f3f3f3f3f3f3f3f;
using namespace std;
int f[maxn];
int v,w,s;
int n,V;
struct node
{
int v;
int w;
}a[maxn];
int main()
{
cin>>n>>V;
f[0] = 0;
int cnt = 0;
for(int i = 1; i<=n; i++)
{
cin>>v>>w>>s;
for(int j = 1; j<=s; j*=2)
{
a[++cnt].v = j*v;
a[cnt].w = j*w;
s -= j;
}
if(s)
{
a[++cnt].v = s*v;
a[cnt].w = s*w;
}
}
for(int i = 1; i<=cnt; i++)
for(int j = V; j>=a[i].v; j--)
f[j] = max(f[j],f[j-a[i].v]+a[i].w);
cout<<f[V]<<endl;
return 0;
}
单调队列优化(待补)
4.混合背包
#include <cstdio>
#include <stack>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
#include <map>
#include <vector>
#include <queue>
#include <set>
#define eps 1e-8
typedef long long ll;
const double PI = acos(-1.0);
const int maxn = 1e6;
const int INF = 0x3f3f3f;
const ll linf = 0x3f3f3f3f3f3f3f3f;
using namespace std;
int f[maxn];
int v,w,s;
int n,V;
struct node
{
int v;
int w;
int type;
}a[maxn];
int main()
{
cin>>n>>V;
f[0] = 0;
int cnt = 0;
for(int i = 1; i<=n; i++)
{
cin>>v>>w>>s;
if(s == -1)
{
a[++cnt].v = v;
a[cnt].w = w;
a[cnt].type = 1;
}
else if(s>0)
{
for(int j = 1; j<=s; j*=2)
{
a[++cnt].v = j*v;
a[cnt].w = j*w;
a[cnt].type = 1;
s -= j;
}
if(s)
{
a[++cnt].v = s*v;
a[cnt].w = s*w;
a[cnt].type = 1;
}
}
else
{
a[++cnt].v = v;
a[cnt].w = w;
a[cnt].type = 0;
}
}
for(int i = 1; i<=cnt; i++)
{
if(a[i].type)
{
for(int j = V; j>=a[i].v; j--)
f[j] = max(f[j],f[j-a[i].v]+a[i].w);
}
else
{
for(int j = a[i].v; j<=V; j++)
f[j] = max(f[j],f[j-a[i].v]+a[i].w);
}
}
cout<<f[V]<<endl;
return 0;
}
5.二维费用背包
#include <cstdio>
#include <stack>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
#include <map>
#include <vector>
#include <queue>
#include <set>
#define eps 1e-8
typedef long long ll;
const double PI = acos(-1.0);
const int maxn = 1005;
const int INF = 0x3f3f3f;
const ll linf = 0x3f3f3f3f3f3f3f3f;
using namespace std;
int f[maxn][maxn];
int v,w,m;
int n,V,M;
int main()
{
cin>>n>>V>>M;
f[0][0] = 0;
int cnt = 0;
for(int i = 1; i<=n; i++)
{
cin>>v>>m>>w;
for(int j = V; j>=v; j--)
for(int k = M; k>=m; k--)
f[j][k] = max(f[j][k],f[j-v][k-m]+w);
}
cout<<f[V][M]<<endl;
return 0;
}
6.分组背包
#include <cstdio>
#include <stack>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
#include <map>
#include <vector>
#include <queue>
#include <set>
#define eps 1e-8
typedef long long ll;
const double PI = acos(-1.0);
const int maxn = 1005;
const int INF = 0x3f3f3f;
const ll linf = 0x3f3f3f3f3f3f3f3f;
using namespace std;
int f[maxn];
int s;
int v[maxn],w[maxn];
int n,V,M;
int main()
{
cin>>n>>V;
f[0] = 0;
for(int i = 0; i<n; i++)
{
cin>>s;
for(int j = 1; j<=s; j++)
cin>>v[j]>>w[j];
for(int j = V; j>=0; j--)
for(int k = 1; k<=s; k++)
{
if(j>=v[k])
f[j] = max(f[j],f[j-v[k]]+w[k]);
}
}
cout<<f[V]<<endl;
return 0;
}
7.有依赖的背包
#include <cstdio>
#include <stack>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
#include <map>
#include <vector>
#include <queue>
#include <set>
#define eps 1e-8
typedef long long ll;
const double PI = acos(-1.0);
const int maxn = 1005;
const int INF = 0x3f3f3f;
const ll linf = 0x3f3f3f3f3f3f3f3f;
using namespace std;
int nxt[maxn],head[maxn],ver[maxn];
int f[maxn][maxn];
int n,V;
int v[maxn],w[maxn];
int tot;
void add(int x, int y)
{
ver[++tot] = y;
nxt[tot] = head[x];
head[x] = tot;
}
void dfs(int u)
{
for(int i = head[u]; i; i = nxt[i])
{
int son = ver[i];
dfs(son);
for(int j = V-v[u]; j>=0; j--)
for(int k = 0; k<=j; k++)
f[u][j] = max(f[u][j],f[u][j-k]+f[son][k]);
}
for(int i = V; i>=v[u]; i--)
f[u][i] = f[u][i-v[u]]+w[u];
for(int i = 0; i<v[u]; i++)
f[u][i] = 0;
}
int main()
{
tot = 0;
cin>>n>>V;
int root;
for(int i = 1; i<=n; i++)
{
int fa;
cin>>v[i]>>w[i]>>fa;
if(fa != -1)
add(fa,i);
else
root = i;
}
dfs(root);
cout<<f[root][V]<<endl;
return 0;
}
8.背包问题求方案数
#include <cstdio>
#include <stack>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
#include <map>
#include <vector>
#include <queue>
#include <set>
#define eps 1e-8
typedef long long ll;
const double PI = acos(-1.0);
const int maxn = 1005;
const int INF = 0x3f3f3f;
const ll linf = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9+7;
using namespace std;
int f[maxn],g[maxn];
int n,V;
int main()
{
cin>>n>>V;
memset(f,0xcf,sizeof f);
f[0] = 0;
g[0] = 1;
for(int i = 0; i<n; i++)
{
int v,w;
cin>>v>>w;
for(int j = V; j>=v; j--)
{
int tmp = max(f[j],f[j-v]+w);
int s = 0;
if(tmp == f[j])
s = g[j]%mod;
if(tmp == f[j-v]+w)
s = (s+(g[j-v]%mod))%mod;
f[j] = tmp;
g[j] = s;
}
}
int maxw = 0;
for(int i = 0; i<=V; i++)
maxw = max(maxw,f[i]);
int res = 0;
for(int i = 0; i<=V; i++)
{
if(f[i] == maxw)
{
res = ((res%mod)+(g[i]%mod))%mod;
}
}
cout<<res<<endl;
return 0;
}
9.背包问题求具体方案
#include <cstdio>
#include <stack>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
#include <map>
#include <vector>
#include <queue>
#include <set>
#define eps 1e-8
typedef long long ll;
const double PI = acos(-1.0);
const int maxn = 1005;
const int INF = 0x3f3f3f;
const ll linf = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9+7;
using namespace std;
int f[maxn][maxn];
int v[maxn],w[maxn];
int n,V;
int main()
{
cin>>n>>V;
for(int i = 1; i<=n; i++)
cin>>v[i]>>w[i];
for(int i = n; i>0; i--)
{
for(int j = 0; j<=V; j++)
{
f[i][j] = f[i+1][j];
if(j>=v[i])
f[i][j] = max(f[i][j],f[i+1][j-v[i]]+w[i]);
}
}
int vol = V;
for(int i = 1; i<=n; i++)
{
if(vol>=v[i] && f[i][vol] == f[i+1][vol-v[i]]+w[i])
{
cout<<i<<" ";
vol -= v[i];
}
}
return 0;
}