01背包:
#include<bits/stdc++.h>
using namespace std;
int v[1005], w[1005], f[1005];
int n, m;
int main() {
//如果题目要求恰好装满
//取最大的时候将f初始化为最小值
//memset(f,128,sizeof(f));
//取最小值的时候,将f初始化为最大值
//memset(f,127,sizeof(f));
//两者都需要再将f[0]=0;
cin >> n >> m;
for (int i = 1; i <= n; i++)
cin >> v[i] >> w[i];
for (int i = 1; i <= n; i++) {
for (int j = m; j >= v[i]; j--) {
f[j] = max(f[j], f[j - v[i]] + w[i]);
}
}
cout << f[m] << endl;
return 0;
}
完全背包:
#include<bits/stdc++.h>
using namespace std;
int n, m;
int v[1005], w[1005], f[1005];
int main() {
//如果要求恰好装满,方式如01背包
cin >> n >> m;
for (int i = 1; i <= n; i++)
cin >> v[i] >> w[i];
for (int i = 1; i <= n; i++) {
for (int j = v[i]; j <= m; j++) {
f[j] = max(f[j], f[j - v[i]] + w[i]);
}
}
cout << f[m] << endl;
return 0;
}
多重背包(小数据范围):
#include<bits/stdc++.h>
using namespace std;
int n, m;
int v[1005], w[1005], l[1005], f[1005];
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++)
cin >> v[i] >> w[i] >> l[i];
for (int i = 1; i <= n; i++)
for (int k = 1; k <= l[i]; k++)
for (int j = m; j >= v[i]; j--)
f[j] = max(f[j], f[j - v[i]] + w[i]);
cout << f[m] << endl;
return 0;
}
多重背包(较大数据范围):
#include<bits/stdc++.h>
using namespace std;
int v[2005], w[2005], l[2005], f[2005];
int n, m;
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++)cin >> v[i] >> w[i] >> l[i];
for (int i = 1; i <= n; i++) {
int res = l[i];
for (int k = 1; k <= res; res -= k, k *= 2) {
for (int j = m; j >= v[i] * k; j--) {
f[j] = max(f[j], f[j - v[i] * k] + w[i] * k);
}
}
for (int j = m; j >= v[i] * res; j--) {
f[j] = max(f[j], f[j - v[i] * res] + w[i] * res);
}
}
cout << f[m] << endl;
return 0;
}
多重背包(特大数据范围):(无脑记模板吧 好像和单调队列有关)
#define _CRT_SECURE_NO_WARNINGS 1
#include<bits/stdc++.h>
#include<unordered_map>
#include<unordered_set>
using namespace std;
#define ll long long
int n, m, v, w, t, f[10005], c[10005][2];
int main(){
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++) {
scanf("%d%d%d", &v, &w, &t);
for (int j = 0; j < v; j++) {
int k = 0, l = 1;
for (int p = j, x = 1; p <= m; p += v, x++) {
int e = f[p] - x * w, r = x + t;
for (; k >= l && c[k][0] <= e; k--);
c[++k][0] = e, c[k][1] = r;
f[p] = c[l][0] + x * w;
for (; k >= l && c[l][1] == x; l++);
}
}
}
printf("%d\n", f[m]);
return 0;
}
分组背包:
#include<bits/stdc++.h>
using namespace std;
int v[1005], w[1005], a[1005], f[1005];
vector<int>c[1005];
int n, m;
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) {
cin >> a[i] >> v[i] >> w[i];
c[a[i]].push_back(i);
}
for (int i = 1; i <= 1000; i++) //有多少组
for (int j = m; j >= 0; j--) //背包容量
for (auto k : c[i])
if (v[k] <= j)
f[j] = max(f[j], f[j - v[k]] + w[k]);
cout << f[m] << endl;
return 0;
}
混合背包视情况而定:
if(符合01背包)用01背包;
if(符合完全背包)就用完全背包
...