原文链接:
http://love-oriented.com/pack/pack2alpha1.pdf
#include
#include
#include
using namespace std;
#define maxV 1000
int main(void) {
int times, n, v, ci, wi;
int f[maxV];
freopen("1.txt", "r", stdin);
cin >> times;
while (times--) {
memset(f, 0, sizeof(f));
cin >> n >> v;
for (int i = 0; i < n; i++) {
cin >> ci >> wi;
for (int j = v; j >= 0; j--) {
if (j >= ci)
f[j] = max(f[j - ci] + wi, f[j]);
}
}
for (int i = 0; i <= v; i++) cout << f[i] << " ";
cout << endl;
cout << f[v] << endl;
}
}
2
4 10
2 4
3 5
4 6
5 10
5 20
3 2
7 3
10 5
15 6
16 10
#include
#include
#include
using namespace std;
#define maxV 1000
int main(void) {
int cases, n, v, ci, wi;
int f[maxV];
freopen("2.txt", "r", stdin);
cin >> cases;
while (cases--) {
memset(f, 0, sizeof(f));
cin >> n >> v;
for (int i = 0; i < n; i++) {
cin >> ci >> wi;
for (int j = 0; j <= v; j++) {
if (j >= ci)
f[j] = max(f[j], f[j - ci] + wi);
}
}
cout << f[v] << endl;
}
}
2
4 10
2 4
3 5
4 6
5 10
5 20
3 2
7 3
10 5
15 6
16 10
#include
#include
using namespace std;
#define maxV 1000
int f[maxV], v;
void ZeroOnePack(int ci, int wi) {
for (int j = v; j >= 0; j--)
if (j >= ci)
f[j] = max(f[j], f[j - ci] + wi);
}
void CompletePack(int ci, int wi) {
for (int j = 0; j <= v; j++)
if (j >= ci)
f[j] = max(f[j], f[j - ci] + wi);
}
void MultiplePack(int ni, int ci, int wi) {
if (ni * ci >= v) {
CompletePack(ci, wi);
return;
}
int k = 1, amount = ni;
while (k < ni) {
ZeroOnePack(ci * k, wi * k);
amount -= k;
k *= 2;
}
ZeroOnePack(ci * amount, wi * amount);
}
int main(void) {
int cases, n, ni, ci, wi;
freopen("3.txt", "r", stdin);
cin >> cases;
while (cases--) {
memset(f, 0, sizeof(f));
cin >> n >> v;
for (int i = 0; i < n; i++) {
cin >> ni >> ci >> wi;
MultiplePack(ni, ci, wi);
}
//for (int i = 0; i <= v; i++) cout << f[i] << " "; cout << endl;
cout << f[v] << endl;
}
}
2
3 10
1 1 10
2 2 4
3 3 11
4 20
5 2 5
2 3 6
3 4 8
1 6 19
#include
#include
using namespace std;
#define maxV 1000
int f[maxV], v;
void ZeroOnePack(int ci, int wi) {
for (int j = v; j >= 0; j--)
if (j >= ci)
f[j] = max(f[j], f[j - ci] + wi);
}
void CompletePack(int ci, int wi) {
for (int j = 0; j <= v; j++)
if (j >= ci)
f[j] = max(f[j], f[j - ci] + wi);
}
void MultiplePack(int ni, int ci, int wi) {
if (ni * ci >= v) {
CompletePack(ci, wi);
return;
}
int k = 1, amount = ni;
while (k < ni) {
ZeroOnePack(ci * k, wi * k);
amount -= k;
k *= 2;
}
ZeroOnePack(ci * amount, wi * amount);
}
int main(void) {
int cases, n, ni, ci, wi;
freopen("4.txt", "r", stdin);
cin >> cases;
while (cases--) {
memset(f, 0, sizeof(f));
cin >> n >> v;
for (int i = 0; i < n; i++) {
cin >> ni >> ci >> wi;
if (ni == 1) ZeroOnePack(ci, wi);
else if (ni == -1) CompletePack(ci, wi);
else MultiplePack(ni, ci, wi);
}
for (int i = 0; i <= v; i++) cout << f[i] << " "; cout << endl;
cout << f[v] << endl;
}
}
2
3 10
-1 1 2
2 2 5
1 3 7
4 20
3 2 5
4 4 6
-1 6 8
1 7 10
#include
#include
#include
using namespace std;
#define maxV 1000
#define maxU 1000
int main(void) {
int cases, n, v, u, ai, bi, wi;
int f[maxV][maxU];
freopen("5.txt", "r", stdin);
cin >> cases;
while (cases--) {
memset(f, 0, sizeof(f));
cin >> n >> v >> u;
for (int i = 0; i < n; i++) {
cin >> ai >> bi >> wi;
for (int j = v; j >= 0; j--) {
for (int k = u; k >= 0; k--) {
if (ai <= j && bi <= k)
f[j][k] = max(f[j][k], f[j - ai][k - bi] + wi);
}
}
}
cout << f[v][u] << endl;
}
}
2
3 10 5
1 2 4
2 1 4
4 4 6
4 5 6
1 1 3
1 2 4
2 1 4
3 4 7
#include
#include
#include
#include
using namespace std;
#define maxV 1000
#define maxG 100
#define maxN 100
int main(void) {
int cases, n, v, g, gi;
int f[maxV];
int ci[maxN], wi[maxN];
freopen("6.txt", "r", stdin);
cin >> cases;
while (cases--) {
memset(f, 0, sizeof(f));
cin >> n >> v >> g;
vector > gMap(g);
for (int i = 0; i < n; i++) {
cin >> ci[i] >> wi[i] >> gi;
gMap[gi].push_back(i);
}
for (int i = 0; i < g; i++) {
for (int j = v; j >= 0; j--) {
for (int k = 0; k < gMap[i].size(); k++) {
if (j >= ci[gMap[i][k]])
f[j] = max(f[j], f[j - ci[gMap[i][k]]] + wi[gMap[i][k]]);
}
}
}
cout << f[v] << endl;
}
}
2
4 10 2
3 5 0
4 6 0
2 7 1
1 6 1
5 10 3
1 3 0
2 4 0
3 5 1
4 7 1
5 8 2
#include
#include
#include
#include
using namespace std;
#define maxV 1000
#define maxG 100
int main(void) {
int cases, n, v, ci[maxV], wi[maxV], di, f[maxV];
freopen("7.txt", "r", stdin);
cin >> cases;
while (cases--) {
memset(f, 0, sizeof(f));
cin >> n >> v;
// group[i]空表示i号物品有依赖,因此存放到其他组里
// 只有一个元素表示i号物品既无依赖也不被依赖
// 有多个元素表示i号物品被依赖,这里自己的编号i也被存放进group[i]
vector > groups(n);
// 读入数据并储存起来
for (int i = 0; i < n; i++) {
cin >> ci[i] >> wi[i] >> di;
if (di == -1) groups[i].push_back(i);
else groups[di].push_back(i);
}
// 对每个有多个元素的组进行01背包
for (int i = 0; i < n; i++) {
if (groups[i].size() > 1) {
vector giOri; //group[i]的拷贝,排除i本身
int newV = v - ci[i];
// 复制group[i]中的元素,排除i
for (int j = 0; j < groups[i].size(); j++) {
if (groups[i][j] != i)
giOri.push_back(groups[i][j]);
}
// 把等效物品组存入group[i]中
groups[i].clear();
groups[i].resize(newV + 1, 0);
for (int j = 0; j < giOri.size(); j++) {
for (int k = newV; k >= 0; k--) {
if (ci[giOri[j]] <= k) {
groups[i][k] = max(groups[i][k], groups[i][k - ci[giOri[j]]] + wi[giOri[j]]);
}
}
}
}
}
// 进行分组背包
for (int i = 0; i < n; i++) {
if (groups[i].size() == 0) continue;
else if (groups[i].size() == 1) { // i物品无依赖且不被依赖
for (int j = v; j >=0; j--) {
if (j >= ci[i])
f[j] = max(f[j], f[j - ci[i]] + wi[i]);
}
} else { // i物品被依赖, i组第k个物品的cost为k + ci[i], weight为group[i][k] + wi[i]
for (int j = v; j >= 0; j--) {
for (int k = 0; k < groups[i].size(); k++) {
if (j >= k + ci[i])
f[j] = max(f[j], f[j - k - ci[i]] + groups[i][k] + wi[i]);
}
}
}
}
cout << f[v] << endl;
}
}
2
3 10
3 5 -1
4 6 0
7 10 0
4 15
4 1 -1
6 8 0
7 10 0
10 4 -1
#include
#include
using namespace std;
#define maxN 100
#define maxV 1000
int n, v;
int cnt = 0;
int head[maxN];
int wi[maxN], ci[maxN];
int f[maxN][maxV];
struct Edge {
int v, next;
} e[maxN - 1];
void addEdge(int u, int v) {
e[cnt].v = v;
e[cnt].next = head[u];
head[u] = cnt++;
}
void treeDP(int u) {
for (int i = ci[u]; i <= v; i++) {
f[u][i] = wi[u];
}
for (int i = head[u]; i != -1; i = e[i].next) {
int curr = e[i].v;
treeDP(curr);
for (int j = v; j >= 0; j--) {
for (int k = j - ci[u]; k >= 0; k--) {
f[u][j] = max(f[u][j], f[u][j - k] + f[curr][k]);
}
}
}
}
int main(void) {
int cases, root;
freopen("8.txt", "r", stdin);
cin >> cases;
while (cases--) {
cnt = 0;
memset(head, -1, sizeof(head));
memset(f, 0, sizeof(f));
cin >> n >> v >> root;
for (int i = 0; i < n; i++) {
int di;
cin >> ci[i] >> wi[i] >> di;
addEdge(di, i);
}
treeDP(root);
cout << f[root][v] << endl;
}
}
2
5 5 0
1 2 -1
2 7 0
2 5 0
2 6 2
1 4 2
6 5 0
1 2 -1
1 3 0
2 3 0
2 4 0
2 7 2
3 10 2
#include
#include
using namespace std;
#define maxV 1000
#define maxN 100
int main(void) {
int cases, n, v, ci[maxN], wi;
int f[maxV];
bool g[maxN][maxV]; //g[i][v]=0 表示没放i时的f(i, v)较大,
//g[i][v]=1 表示放进i时的f(i, v)较大
freopen("9.txt", "r", stdin);
cin >> cases;
while (cases--) {
memset(f, 0, sizeof(f));
memset(g, 0, sizeof(g));
cin >> n >> v;
for (int i = 0; i < n; i++) {
cin >> ci[i] >> wi;
for (int j = v; j >= 0; j--) {
if (j >= ci[i]) {
if (f[j - ci[i]] + wi > f[j]) {
f[j] = f[j - ci[i]] + wi;
g[i][j] = 1;
}
}
}
}
int i = n - 1, j = v;
while (i >= 0) {
if (g[i][j] == 1) {
cout << "选了" << i << endl;
j -= ci[i];
} else {
cout << "没选" << i << endl;
}
i--;
}
cout << endl;
}
}
2
4 10
2 4
3 5
4 6
5 10
5 20
3 2
7 3
10 5
15 6
16 10