Reputation: 957
I am working on some task which requires from me to solve the following algorithmic problem:
So this is not "Knapsack 0/1" problem, as we deal only with weights (we have only one parameter for item). Therefore I assume that it might have a solution (Knapsack is NP-complete) or some kind of algorithm which gives approximately correct result.
Please don't suggest me "greedy algorithms", because I believe that there should be an algorithm which gives better results. I think that it should be an algorithm which uses "dynamic programming".
Thank you in advance :)
Upvotes: 3
Views: 7554
Reputation: 2138
It look like Spoj problem. And my solusion to solve:
#include <bits/stdc++.h>
using namespace std;
int TimTongLonNhatCoGioiHan(int*arr, int songuoichoi, int gioihan){
int hmm = (int)(songuoichoi*songuoichoi/2);
int map[hmm];
int dem = 0, i, j, ox = songuoichoi - 1, oy = 0, result = 0, sum;
for(i = ox; i > oy; --i){
for(j = oy; j < ox; ++j){
map[dem] = arr[i] + arr[j];
// tinh tong lon nhat cua 3 so
for(int k = 0; k < songuoichoi; ++k){
if(k == j || k == i)
continue;
sum = map[dem] + arr[k];
if(sum > result && sum <= gioihan)
result = sum;
}
dem++;
}
-- ox;
}
return result;
}
int main() {
int sophantu = 0, songuoichoi = 0, gioihan = 0;
cin>>sophantu;
while(sophantu-->0){
cin>>songuoichoi;
int i = 0;
int arrCanNang[songuoichoi];
for(; i<songuoichoi; ++i){
cin>>arrCanNang[i];
}
cin>>gioihan;
cout<<TimTongLonNhatCoGioiHan(arrCanNang, songuoichoi, gioihan)<<"\n";
}
return 0;
}
For simple, you can create a matrix [w1, w2, ..., wn] x [w1, w2, ..., wn], put sum(Wi, Wj), foreach k and find MAX sum(Wi, Wj) + Wk.
Upvotes: 0
Reputation: 43662
In this particular instance you get maximum benefit by minimizing the free space in the bag and therefore by considering weight as a value. This problem is commonly referred to as subset sum problem and is a particular case of knapsack problems family.
The DP relation looks like the following
where at each step you try to find the maximum value (which does not exceed the bag's capacity) among the previous elements set plus the new element
A C++ implementation of the subset sum problem to answer the question "can I fill the bag entirely given these elements?" and driver follows
bool ssp(const vector<int>& v, const int& N) {
vector<vector<int>> m( v.size() + 1 /* 1-based */,
vector<int>(N + 1 /* 1-based */, 0) );
// The line above also took care of the initialization for base
// cases f(i,0) = 0 and f(0,b) = 0
for (int i = 1; i <= v.size(); ++i) { // For each subset of elements
for (int b = 1; b <= N; ++b) { // For each subcapacity
int opt1 = m[i - 1][b];
int opt2 = -1;
if (b - v[i - 1] >= 0) { // No caching to keep this readable
opt2 = m[i - 1][b - v[i - 1]] + v[i - 1];
if (opt2 > b)
opt2 = -1; // Not allowed
}
m[i][b] = max(opt1, opt2);
}
}
return (m[v.size()][N] == N);
}
int main() {
const vector<int> v = { 1, 3, 7, 4 };
const int N = 11;
cout << "Subset sum problem can be solved with the given input: "
<< boolalpha << ssp(v, N); // true
return 0;
}
The complexity is O(N⋅I)
where I
is the number of elements in the starting set. This is a pseudopolynomial complexity.
Source: Knapsack problem
Upvotes: 2
Reputation: 17605
The described problem in fact is not the 0-1-Knapsack problem, but a special case thereof, also called the Maximum Subset Sum problem, which is desribed here. It is NP
-complete, which means that it is not easier than 0-1-Knapsack complexity-wise.
That being said, it can be solved by any optimization algorithm intended for the 0-1-Knapsack problem by setting the item profits equal to their weights. In total, it can be solved to optimality using the following dynamic programming algorithm; s[i]
denotes the size if the i
-th item and m
is an integer-valued state space where m[i,s]
denotes the maximum value attainable by using items from the item rage {0,...i}
.
for j from 0 to W do:
m[0, j] := 0
for i from 1 to n do:
for j from 0 to W do:
if s[i] > j then:
m[i, j] := m[i-1, j]
else:
m[i, j] := max(m[i-1, j], m[i-1, j-s[i]] + s[i])
As they are mentioned in the original question, the following greedy algorithm yields a 2-approximation, which is a modification of a similar algorithm for the Knapsack problem.
1. select any subset of the items such that there is no other
item which can be feasibly chosen
2. select the largest item
3. out of 1. and 2., choose the subset which yields the larger total size
Upvotes: 2