原文链接:
http://love-oriented.com/pack/pack2alpha1.pdf
#include <iostream> #include <cstring> #include <algorithm> 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 <iostream> #include <cstring> #include <algorithm> 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 <iostream> #include <algorithm> 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 <iostream> #include <cstring> 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 <iostream> #include <cstring> #include <algorithm> 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 <iostream> #include <cstring> #include <vector> #include <algorithm> 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<vector<int> > 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 <iostream> #include <vector> #include <cstring> #include <algorithm> 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<vector<int> > 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<int> 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 <iostream> #include <algorithm> 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 <iostream> #include <algorithm> 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