Minimum difference between the highest and the smallest value of mines distributed - c++
Given Question: Given n companies and m oil mines with values, design an algorithm to
distribute the sites among the companies in a fair manner, where the company getting the highest
total value of its assigned sites and the one getting the lowest total value is minimal. Your
algorithm should output this minimum difference. Note that oil mines sites assigned to each
company should be adjacent to each other, and that the number of mines m is always bigger than
or equal to the number of companies n
Sample Input: Input : n = 3, site values = [6, 10, 13, 2]
Output : 9 → for the assignment of [6] to company #1, [10] to company #2, and [13, 2]
to company #3, making the minimum difference (13+2) - 6 = 9
My attempt at solving:
Add all previous elements in array, so the new array becomes [6, 16, 29, 31].
Then, I form all possible solution arrays which are: note: 31 stays constant because it is the largest and I need to subtract the largest from the smallest
31, 29, 16
31, 29, 6
31, 16, 6
Then, I subtract all previous elements in array, so the new arrays become
2, 13, 16
2, 23, 6
15, 10, 6
Then I subtract the highest number from the lowest number in each array which would be:
16 - 2 = 14
23 - 2 = 21
15 - 6 = 9 // **answer**
I would pick the smallest difference which is 9
My question:
(1) Is there an easier way to solve this? As this seems like it a bit too complex and I'm just overthinking things. (2) How would I go about implementing generating all the possible combinations to the array? Should I use permutations? Recursion? This is the part that I'm stuck on the most, generating all possible solutions where 31 (in the example stays the same) and I select only 2 out of the 3 other elements in the array.
void Func (int n, int m, int prosValues[], int solArray[], bool summed) {
if (!summed) {
for (int i = 1; i < m; i++) {
prosValues[i] = prosValues[i] + prosValues[i-1];
}
solArray[0] = prosValues[m-1];
summed = true;
}
// generate all possible combinations as shown in example
}
Interesting problem! I chose a different approach to solve this. I don't know, if it is more elegant, but I spend some time thinking about it and wanted to share my solution at least.
I make the following convention for the site assignment:
The indices in the site array describe the start index for site values, from which the site values are assigned to that site. Let's make it clearer using two examples.
values = {2,6,3,8,2,1}
sites1 = {0,1,2}
sites2 = {0,2,5}
The two site distributions site1 and site2 will assign the site values as follows:
distribution for site1:
0: 2
1: 6
2: 3, 8, 2, 1
distribution for site2:
0: 2, 6
1: 3, 8
2: 2, 1
This way we can iterate through all combinations by shifting the indices in sites up. In the example for 6 site values, we would get:
{0,1,2}
{0,1,3}
{0,1,4}
{0,1,5}
{0,2,3}
{0,2,4}
{0,2,5}
{0,3,4}
{0,3,5}
{0,4,5}
{1,2,3}
{1,3,4}
{1,3,5}
.
.
.
{3,4,5}
For all these site distributions we sum up the site values for each site, calculate the maximum difference and pick the distribution with the smallest difference.
Putting it all together, here is the code I came up with:
#include <iostream>
#include <algorithm>
int calc_diff(int m, int n, int* values, int* sites)
{
// stores the sum of values for each site
int *result = new int[n] {0};
// iterate through all site values
for (int j = 0; j < m; j++)
{
// find the correct site index to which the value is assigned
int index = 0;
for (int i = n-1; i >= 0; i--)
{
if (j >= sites[i])
{
index = i;
break;
}
}
// sum up the site vaues
result[index] += values[j];
// debug print
// std::cout << index << ":\t" << result[index] << std::endl;
}
// print the site results
std::cout << "result:\t";
for (int i = 0; i < n; i++)
std::cout << result[i] << "\t";
// get the highest difference
auto min = std::min_element(result, result+n);
auto max = std::max_element(result, result+n);
int diff = *max - *min;
delete[] result;
return diff;
}
int main()
{
int n = 3;
int m = 6;
auto values = new int[m] {2,6,3,8,2,1};
auto sites = new int[n] {0,1,2};
// start index of the first site
int start_index = 0;
// current best difference (some really high number)
int max = 100000000;
// the current best solution
auto best = new int[n];
bool end = false;
while(!end)
{
std::cout << "sites:\t";
for (int i = 0; i < n; i++)
std::cout << sites[i] << "\t";
std::cout << std::endl;
// calculate the maximal difference of the current site distribution
auto diff = calc_diff(m, n, values, sites);
std::cout << "\nmax diff:\t" << diff << std::endl << std::endl;
// if we find a better solution than the current best, we store it as new best solution
if (diff < max)
{
max = diff;
memcpy(best, sites, n*sizeof(int));
}
// calculate new site distribution
int index = 0;
for (int i = n-1; i >= 0; i--)
{
// get the current index
index = sites[i];
// can we still move the index one position up?
// the index of the last site should not exceed m-1
// the index of all other sites should be less than the index of the next site
if ((i == n-1 && index < m-1) ||
(i < n-1 && i > 0 && index < sites[i+1]-1))
{
// increase the index of the current site
sites[i]++;
break;
}
// all site index have moved to maximum position?
// (we iterated through all indices (so i=0) and moved none of them)
if (i == 0)
{
// increase the start index of the first site
start_index++;
// reset the indices by starting from the current start_index
for (int j = 1; j < n; j++)
{
sites[j] = start_index + j;
// if we exceed the numbers of site values, we can stop the loop
if (sites[j] >= m)
end = true;
}
}
}
}
// print best soluition
std::cout << "Best distribution: ";
for (int i = 0; i < n; i++)
std::cout << best[i] << " ";
delete[] sites;
delete[] values;
delete[] best;
}
Related
How to find all possible combinations of adding two variables, each attached to a multiplier, summing up to a given number (cin)?
In my situation, a lorry has a capacity of 30, while a van has a capacity of 10. I need to find the number of vans/lorries needed to transport a given amount of cargo, say 100. I need to find all possible combinations of lorries + vans that will add up to 100. The basic math calculation would be: (30*lorrycount) + (10*vancount) = n, where n is number of cargo. Output Example Cargo to be transported: 100 Number of Lorry: 0 3 2 1 Number of Van: 10 1 4 7 For example, the 2nd combination is 3 lorries, 1 van. Considering that lorries have capacity = 30 and van capacity = 10, (30*3)+(10*1) = 100 = n. For now, we only have this code, which finds literally all combinations of numbers that add up to given number n, without considering the formula given above. #include <iostream> #include <vector> using namespace std; void findCombinationsUtil(int arr[], int index, int num, int reducedNum) { int lorry_capacity = 30; int van_capacity = 10; // Base condition if (reducedNum < 0) return; // If combination is found, print it if (reducedNum == 0) { for (int i = 0; i < index; i++) cout << arr[i] << " "; cout << endl; return; } // Find the previous number stored in arr[] // It helps in maintaining increasing order int prev = (index == 0) ? 1 : arr[index - 1]; // note loop starts from previous number // i.e. at array location index - 1 for (int k = prev; k <= num; k++) { // next element of array is k arr[index] = k; // call recursively with reduced number findCombinationsUtil(arr, index + 1, num, reducedNum - k); } } void findCombinations(int n) { // array to store the combinations // It can contain max n elements std::vector<int> arr(n); // allocate n elements //find all combinations findCombinationsUtil(&*arr.begin(), 0, n, n); } int main() { int n; cout << "Enter the amount of cargo you want to transport: "; cin >> n; cout << endl; //const int n = 10; findCombinations(n); return 0; } Do let me know if you have any solution to this, thank you.
An iterative way of finding all possible combinations #include <iostream> #include <vector> int main() { int cw = 100; int lw = 30, vw = 10; int maxl = cw/lw; // maximum no. of lorries that can be there std::vector<std::pair<int,int>> solutions; // for the inclusive range of 0 to maxl, find the corresponding no. of vans for each variant of no of lorries for(int l = 0; l<= maxl; ++l){ bool is_integer = (cw - l*lw)%vw == 0; // only if this is true, then there is an integer which satisfies for given l if(is_integer){ int v = (cw-l*lw)/vw; // no of vans solutions.push_back(std::make_pair(l,v)); } } for( auto& solution : solutions){ std::cout<<solution.first<<" lorries and "<< solution.second<<" vans" <<std::endl; } return 0; }
We will create a recursive function that walks a global capacities array left to right and tries to load cargo into the various vehicle types. We keep track of how much we still have to load and pass that on to any recursive call. If we reach the end of the array, we produce a solution only if the remaining cargo is zero. std::vector<int> capacities = { 30, 10 }; using Solution = std::vector<int>; using Solutions = std::vector<Solution>; void tryLoad(int remaining_cargo, int vehicle_index, Solution so_far, std::back_insert_iterator<Solutions>& solutions) { if (vehicle_index == capacities.size()) { if (remaining_cargo == 0) // we have a solution *solutions++ = so_far; return; } int capacity = capacities[vehicle_index]; for (int vehicles = 0; vehicles <= remaining_cargo / capacity; vehicles++) { Solution new_solution = so_far; new_solution.push_back(vehicles); tryLoad(remaining_cargo - vehicles * capacity, vehicle_index + 1, new_solution, solutions); } } Calling this as follows should produce the desired output in all_solutions: Solutions all_solutions; auto inserter = std::back_inserter(all_solutions) tryLoad(100, 0, Solution{}, inserter);
Divide elements of a sorted array into least number of groups such that difference between the elements of the new array is less than or equal to 1
How to divide elements in an array into a minimum number of arrays such that the difference between the values of elements of each of the formed arrays does not differ by more than 1? Let's say that we have an array: [4, 6, 8, 9, 10, 11, 14, 16, 17]. The array elements are sorted. I want to divide the elements of the array into a minimum number of array(s) such that each of the elements in the resulting arrays do not differ by more than 1. In this case, the groupings would be: [4], [6], [8, 9, 10, 11], [14], [16, 17]. So there would be a total of 5 groups. How can I write a program for the same? Or you can suggest algorithms as well. I tried the naive approach: Obtain the difference between consecutive elements of the array and if the difference is less than (or equal to) 1, I add those elements to a new vector. However this method is very unoptimized and straight up fails to show any results for a large number of inputs. Actual code implementation: #include<cstdio> #include<iostream> #include<vector> using namespace std; int main() { int num = 0, buff = 0, min_groups = 1; // min_groups should start from 1 to take into account the grouping of the starting array element(s) cout << "Enter the number of elements in the array: " << endl; cin >> num; vector<int> ungrouped; cout << "Please enter the elements of the array: " << endl; for (int i = 0; i < num; i++) { cin >> buff; ungrouped.push_back(buff); } for (int i = 1; i < ungrouped.size(); i++) { if ((ungrouped[i] - ungrouped[i - 1]) > 1) { min_groups++; } } cout << "The elements of entered vector can be split into " << min_groups << " groups." << endl; return 0; }
Inspired by Faruk's answer, if the values are constrained to be distinct integers, there is a possibly sublinear method. Indeed, if the difference between two values equals the difference between their indexes, they are guaranteed to belong to the same group and there is no need to look at the intermediate values. You have to organize a recursive traversal of the array, in preorder. Before subdividing a subarray, you compare the difference of indexes of the first and last element to the difference of values, and only subdivide in case of a mismatch. As you work in preorder, this will allow you to emit pieces of the groups in consecutive order, as well as detect to the gaps. Some care has to be taken to merge the pieces of the groups. The worst case will remain linear, because the recursive traversal can degenerate to a linear traversal (but not worse than that). The best case can be better. In particular, if the array holds a single group, it will be found in time O(1). If I am right, for every group of length between 2^n and 2^(n+1), you will spare at least 2^(n-1) tests. (In fact, it should be possible to estimate an output-sensitive complexity, equal to the array length minus a fraction of the lengths of all groups, or similar.) Alternatively, you can work in a non-recursive way, by means of exponential search: from the beginning of a group, you start with a unit step and double the step every time, until you detect a gap (difference in values too large); then you restart with a unit step. Here again, for large groups you will skip a significant number of elements. Anyway, the best case can only be O(Log(N)).
I would suggest encoding subsets into an offset array defined as follows: Elements for set #i are defined for indices j such that offset[i] <= j < offset[i+1] The number of subsets is offset.size() - 1 This only requires one memory allocation. Here is a complete implementation: #include <cassert> #include <iostream> #include <vector> std::vector<std::size_t> split(const std::vector<int>& to_split, const int max_dist = 1) { const std::size_t to_split_size = to_split.size(); std::vector<std::size_t> offset(to_split_size + 1); offset[0] = 0; size_t offset_idx = 1; for (std::size_t i = 1; i < to_split_size; i++) { const int dist = to_split[i] - to_split[i - 1]; assert(dist >= 0); // we assumed sorted input if (dist > max_dist) { offset[offset_idx] = i; ++offset_idx; } } offset[offset_idx] = to_split_size; offset.resize(offset_idx + 1); return offset; } void print_partition(const std::vector<int>& to_split, const std::vector<std::size_t>& offset) { const std::size_t offset_size = offset.size(); std::cout << "\nwe found " << offset_size-1 << " sets"; for (std::size_t i = 0; i + 1 < offset_size; i++) { std::cout << "\n"; for (std::size_t j = offset[i]; j < offset[i + 1]; j++) { std::cout << to_split[j] << " "; } } } int main() { std::vector<int> to_split{4, 6, 8, 9, 10, 11, 14, 16, 17}; std::vector<std::size_t> offset = split(to_split); print_partition(to_split, offset); } which prints: we found 5 sets 4 6 8 9 10 11 14 16 17
Iterate through the array. Whenever the difference between 2 consecutive element is greater than 1, add 1 to your answer variable. ` int getPartitionNumber(int arr[]) { //let n be the size of the array; int result = 1; for(int i=1; i<n; i++) { if(arr[i]-arr[i-1] > 1) result++; } return result; } `
And because it is always nice to see more ideas and select the one that suites you best, here the straight forward 6 line solution. Yes, it is also O(n). But I am not sure, if the overhead for other methods makes it faster. Please see: #include <iostream> #include <string> #include <algorithm> #include <vector> #include <iterator> using Data = std::vector<int>; using Partition = std::vector<Data>; Data testData{ 4, 6, 8, 9, 10, 11, 14, 16, 17 }; int main(void) { // This is the resulting vector of vectors with the partitions std::vector<std::vector<int>> partition{}; // Iterating over source values for (Data::iterator i = testData.begin(); i != testData.end(); ++i) { // Check,if we need to add a new partition // Either, at the beginning or if diff > 1 // No underflow, becuase of boolean shortcut evaluation if ((i == testData.begin()) || ((*i) - (*(i-1)) > 1)) { // Create a new partition partition.emplace_back(Data()); } // And, store the value in the current partition partition.back().push_back(*i); } // Debug output: Copy all data to std::cout std::for_each(partition.begin(), partition.end(), [](const Data& d) {std::copy(d.begin(), d.end(), std::ostream_iterator<int>(std::cout, " ")); std::cout << '\n'; }); return 0; } Maybe this could be a solution . . .
How do you say your approach is not optimized? If your is correct, then according to your approach, it takes O(n) time complexity. But you can use binary-search here which can optimize in average case. But in worst case this binary search can take more than O(n) time complexity. Here's a tips, As the array sorted so you will pick such a position whose difference is at most 1. Binary search can do this in simple way. int arr[] = [4, 6, 8, 9, 10, 11, 14, 16, 17]; int st = 0, ed = n-1; // n = size of the array. int partitions = 0; while(st <= ed) { int low = st, high = n-1; int pos = low; while(low <= high) { int mid = (low + high)/2; if((arr[mid] - arr[st]) <= 1) { pos = mid; low = mid + 1; } else { high = mid - 1; } } partitions++; st = pos + 1; } cout<< partitions <<endl; In average case, it is better than O(n). But in worst case (where the answer would be equal to n) it takes O(nlog(n)) time.
Power set of large set
I have to calculate power set of set which may have more elements upto 10^5. I tried an algo and the code below but it failed (I think cause large value of pow(2, size)). void printPowerSet(int *set, int set_size) { unsigned int pow_set_size = pow(2, set_size); int counter, j,sum=0; for(counter = 0; counter < pow_set_size; counter++) { for(j = 0; j < set_size; j++) { if(counter & (1<<j)) std::cout<<set[i]<<" "; } std::cout<<sum; sum=0; printf("\n"); } } Is there any other algorithm or how can I fix this one (if it is possible)?? OR Can you suggest me how to do it i.e. finding subset of large set. As pointed out in an answer it seems I'm stuck in X-Y problem. Basically, I need sum of all subsets of any set. Now if you can suggest me any other approach to solve the problem. Thank you.
Here is an algorithm which will print out the power set of any set that will fit in your computer's memory. Given enough time, it will print the power set of a set of length 10^5. However, "enough time" will be something like several trillion billion gazillion years. c++14 #include <iostream> #include <vector> #include <algorithm> using namespace std; #include <iostream> void printPowerset (const vector<int>& original_set) { auto print_set = [&original_set](auto first, auto last) -> ostream& { cout << '('; auto sep = ""; for ( ; first != last ; ++first, sep = ",") { cout << sep << original_set[(*first) - 1]; } return cout << ')'; }; const int n = original_set.size(); std::vector<int> index_stack(n + 1, 0); int k = 0; while(1){ if (index_stack[k]<n){ index_stack[k+1] = index_stack[k] + 1; k++; } else{ index_stack[k-1]++; k--; } if (k==0) break; print_set(begin(index_stack) + 1, begin(index_stack) + 1 + k); } print_set(begin(index_stack), begin(index_stack)) << endl; } int main(){ auto nums = vector<int> { 2, 4, 6, 8 }; printPowerset(nums); nums = vector<int> { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 }; printPowerset(nums); return 0; } expected results: first power set (4 items): (2)(2,4)(2,4,6)(2,4,6,8)(2,4,8)(2,6)(2,6,8)(2,8)(4)(4,6)(4,6,8)(4,8)(6)(6,8)(8)() second power set (10 items) (2)(2,4)(2,4,6)(2,4,6,8)(2,4,6,8,10)(2,4,6,8,10,12)(2,4,6,8,10,12,14)(2,4,6,8,10,12,14,16)(2,4,6,8,10,12,14,16,18)(2,4,6,8,10,12,14,16,18,20)(2,4,6,8,10,12,14,16,20)(2,4,6,8,10,12,14,18)(2,4,6,8,10,12,14,18,20)(2,4,6,8,10,12,14,20)(2,4,6,8,10,12,16)(2,4,6,8,10,12,16,18)(2,4,6,8,10,12,16,18,20)(2,4,6,8,10,12,16,20)(2,4,6,8,10,12,18)(2,4,6,8,10,12,18,20)(2,4,6,8,10,12,20)(2,4,6,8,10,14)(2,4,6,8,10,14,16)(2,4,6,8,10,14,16,18)(2,4,6,8,10,14,16,18,20)(2,4,6,8,10,14,16,20)(2,4,6,8,10,14,18)(2,4,6,8,10,14,18,20)(2,4,6,8,10,14,20)(2,4,6,8,10,16)(2,4,6,8,10,16,18)(2,4,6,8,10,16,18,20)(2,4,6,8,10,16,20)(2,4,6,8,10,18)(2,4,6,8,10,18,20)(2,4,6,8,10,20)(2,4,6,8,12)(2,4,6,8,12,14)(2,4,6,8,12,14,16)(2,4,6,8,12,14,16,18)(2,4,6,8,12,14,16,18,20)(2,4,6,8,12,14,16,20)(2,4,6,8,12,14,18)(2,4,6,8,12,14,18,20)(2,4,6,8,12,14,20)(2,4,6,8,12,16)(2,4,6,8,12,16,18)(2,4,6,8,12,16,18,20)(2,4,6,8,12,16,20)(2,4,6,8,12,18)(2,4,6,8,12,18,20)(2,4,6,8,12,20)(2,4,6,8,14)(2,4,6,8,14,16)(2,4,6,8,14,16,18)(2,4,6,8,14,16,18,20)(2,4,6,8,14,16,20)(2,4,6,8,14,18)(2,4,6,8,14,18,20)(2,4,6,8,14,20)(2,4,6,8,16)(2,4,6,8,16,18)(2,4,6,8,16,18,20)(2,4,6,8,16,20)(2,4,6,8,18)(2,4,6,8,18,20)(2,4,6,8,20)(2,4,6,10)(2,4,6,10,12)(2,4,6,10,12,14)(2,4,6,10,12,14,16)(2,4,6,10,12,14,16,18)(2,4,6,10,12,14,16,18,20)(2,4,6,10,12,14,16,20)(2,4,6,10,12,14,18)(2,4,6,10,12,14,18,20)(2,4,6,10,12,14,20)(2,4,6,10,12,16)(2,4,6,10,12,16,18)(2,4,6,10,12,16,18,20)(2,4,6,10,12,16,20)(2,4,6,10,12,18)(2,4,6,10,12,18,20)(2,4,6,10,12,20)(2,4,6,10,14)(2,4,6,10,14,16)(2,4,6,10,14,16,18)(2,4,6,10,14,16,18,20)(2,4,6,10,14,16,20)(2,4,6,10,14,18)(2,4,6,10,14,18,20)(2,4,6,10,14,20)(2,4,6,10,16)(2,4,6,10,16,18)(2,4,6,10,16,18,20)(2,4,6,10,16,20)(2,4,6,10,18)(2,4,6,10,18,20)(2,4,6,10,20)(2,4,6,12)(2,4,6,12,14)(2,4,6,12,14,16)(2,4,6,12,14,16,18)(2,4,6,12,14,16,18,20)(2,4,6,12,14,16,20)(2,4,6,12,14,18)(2,4,6,12,14,18,20)(2,4,6,12,14,20)(2,4,6,12,16)(2,4,6,12,16,18)(2,4,6,12,16,18,20)(2,4,6,12,16,20)(2,4,6,12,18)(2,4,6,12,18,20)(2,4,6,12,20)(2,4,6,14)(2,4,6,14,16)(2,4,6,14,16,18)(2,4,6,14,16,18,20)(2,4,6,14,16,20)(2,4,6,14,18)(2,4,6,14,18,20)(2,4,6,14,20)(2,4,6,16)(2,4,6,16,18)(2,4,6,16,18,20)(2,4,6,16,20)(2,4,6,18)(2,4,6,18,20)(2,4,6,20)(2,4,8)(2,4,8,10)(2,4,8,10,12)(2,4,8,10,12,14)(2,4,8,10,12,14,16)(2,4,8,10,12,14,16,18)(2,4,8,10,12,14,16,18,20)(2,4,8,10,12,14,16,20)(2,4,8,10,12,14,18)(2,4,8,10,12,14,18,20)(2,4,8,10,12,14,20)(2,4,8,10,12,16)(2,4,8,10,12,16,18)(2,4,8,10,12,16,18,20)(2,4,8,10,12,16,20)(2,4,8,10,12,18)(2,4,8,10,12,18,20)(2,4,8,10,12,20)(2,4,8,10,14)(2,4,8,10,14,16)(2,4,8,10,14,16,18)(2,4,8,10,14,16,18,20)(2,4,8,10,14,16,20)(2,4,8,10,14,18)(2,4,8,10,14,18,20)(2,4,8,10,14,20)(2,4,8,10,16)(2,4,8,10,16,18)(2,4,8,10,16,18,20)(2,4,8,10,16,20)(2,4,8,10,18)(2,4,8,10,18,20)(2,4,8,10,20)(2,4,8,12)(2,4,8,12,14)(2,4,8,12,14,16)(2,4,8,12,14,16,18)(2,4,8,12,14,16,18,20)(2,4,8,12,14,16,20)(2,4,8,12,14,18)(2,4,8,12,14,18,20)(2,4,8,12,14,20)(2,4,8,12,16)(2,4,8,12,16,18)(2,4,8,12,16,18,20)(2,4,8,12,16,20)(2,4,8,12,18)(2,4,8,12,18,20)(2,4,8,12,20)(2,4,8,14)(2,4,8,14,16)(2,4,8,14,16,18)(2,4,8,14,16,18,20)(2,4,8,14,16,20)(2,4,8,14,18)(2,4,8,14,18,20)(2,4,8,14,20)(2,4,8,16)(2,4,8,16,18)(2,4,8,16,18,20)(2,4,8,16,20)(2,4,8,18)(2,4,8,18,20)(2,4,8,20)(2,4,10)(2,4,10,12)(2,4,10,12,14)(2,4,10,12,14,16)(2,4,10,12,14,16,18)(2,4,10,12,14,16,18,20)(2,4,10,12,14,16,20)(2,4,10,12,14,18)(2,4,10,12,14,18,20)(2,4,10,12,14,20)(2,4,10,12,16)(2,4,10,12,16,18)(2,4,10,12,16,18,20)(2,4,10,12,16,20)(2,4,10,12,18)(2,4,10,12,18,20)(2,4,10,12,20)(2,4,10,14)(2,4,10,14,16)(2,4,10,14,16,18)(2,4,10,14,16,18,20)(2,4,10,14,16,20)(2,4,10,14,18)(2,4,10,14,18,20)(2,4,10,14,20)(2,4,10,16)(2,4,10,16,18)(2,4,10,16,18,20)(2,4,10,16,20)(2,4,10,18)(2,4,10,18,20)(2,4,10,20)(2,4,12)(2,4,12,14)(2,4,12,14,16)(2,4,12,14,16,18)(2,4,12,14,16,18,20)(2,4,12,14,16,20)(2,4,12,14,18)(2,4,12,14,18,20)(2,4,12,14,20)(2,4,12,16)(2,4,12,16,18)(2,4,12,16,18,20)(2,4,12,16,20)(2,4,12,18)(2,4,12,18,20)(2,4,12,20)(2,4,14)(2,4,14,16)(2,4,14,16,18)(2,4,14,16,18,20)(2,4,14,16,20)(2,4,14,18)(2,4,14,18,20)(2,4,14,20)(2,4,16)(2,4,16,18)(2,4,16,18,20)(2,4,16,20)(2,4,18)(2,4,18,20)(2,4,20)(2,6)(2,6,8)(2,6,8,10)(2,6,8,10,12)(2,6,8,10,12,14)(2,6,8,10,12,14,16)(2,6,8,10,12,14,16,18)(2,6,8,10,12,14,16,18,20)(2,6,8,10,12,14,16,20)(2,6,8,10,12,14,18)(2,6,8,10,12,14,18,20)(2,6,8,10,12,14,20)(2,6,8,10,12,16)(2,6,8,10,12,16,18)(2,6,8,10,12,16,18,20)(2,6,8,10,12,16,20)(2,6,8,10,12,18)(2,6,8,10,12,18,20)(2,6,8,10,12,20)(2,6,8,10,14)(2,6,8,10,14,16)(2,6,8,10,14,16,18)(2,6,8,10,14,16,18,20)(2,6,8,10,14,16,20)(2,6,8,10,14,18)(2,6,8,10,14,18,20)(2,6,8,10,14,20)(2,6,8,10,16)(2,6,8,10,16,18)(2,6,8,10,16,18,20)(2,6,8,10,16,20)(2,6,8,10,18)(2,6,8,10,18,20)(2,6,8,10,20)(2,6,8,12)(2,6,8,12,14)(2,6,8,12,14,16)(2,6,8,12,14,16,18)(2,6,8,12,14,16,18,20)(2,6,8,12,14,16,20)(2,6,8,12,14,18)(2,6,8,12,14,18,20)(2,6,8,12,14,20)(2,6,8,12,16)(2,6,8,12,16,18)(2,6,8,12,16,18,20)(2,6,8,12,16,20)(2,6,8,12,18)(2,6,8,12,18,20)(2,6,8,12,20)(2,6,8,14)(2,6,8,14,16)(2,6,8,14,16,18)(2,6,8,14,16,18,20)(2,6,8,14,16,20)(2,6,8,14,18)(2,6,8,14,18,20)(2,6,8,14,20)(2,6,8,16)(2,6,8,16,18)(2,6,8,16,18,20)(2,6,8,16,20)(2,6,8,18)(2,6,8,18,20)(2,6,8,20)(2,6,10)(2,6,10,12)(2,6,10,12,14)(2,6,10,12,14,16)(2,6,10,12,14,16,18)(2,6,10,12,14,16,18,20)(2,6,10,12,14,16,20)(2,6,10,12,14,18)(2,6,10,12,14,18,20)(2,6,10,12,14,20)(2,6,10,12,16)(2,6,10,12,16,18)(2,6,10,12,16,18,20)(2,6,10,12,16,20)(2,6,10,12,18)(2,6,10,12,18,20)(2,6,10,12,20)(2,6,10,14)(2,6,10,14,16)(2,6,10,14,16,18)(2,6,10,14,16,18,20)(2,6,10,14,16,20)(2,6,10,14,18)(2,6,10,14,18,20)(2,6,10,14,20)(2,6,10,16)(2,6,10,16,18)(2,6,10,16,18,20)(2,6,10,16,20)(2,6,10,18)(2,6,10,18,20)(2,6,10,20)(2,6,12)(2,6,12,14)(2,6,12,14,16)(2,6,12,14,16,18)(2,6,12,14,16,18,20)(2,6,12,14,16,20)(2,6,12,14,18)(2,6,12,14,18,20)(2,6,12,14,20)(2,6,12,16)(2,6,12,16,18)(2,6,12,16,18,20)(2,6,12,16,20)(2,6,12,18)(2,6,12,18,20)(2,6,12,20)(2,6,14)(2,6,14,16)(2,6,14,16,18)(2,6,14,16,18,20)(2,6,14,16,20)(2,6,14,18)(2,6,14,18,20)(2,6,14,20)(2,6,16)(2,6,16,18)(2,6,16,18,20)(2,6,16,20)(2,6,18)(2,6,18,20)(2,6,20)(2,8)(2,8,10)(2,8,10,12)(2,8,10,12,14)(2,8,10,12,14,16)(2,8,10,12,14,16,18)(2,8,10,12,14,16,18,20)(2,8,10,12,14,16,20)(2,8,10,12,14,18)(2,8,10,12,14,18,20)(2,8,10,12,14,20)(2,8,10,12,16)(2,8,10,12,16,18)(2,8,10,12,16,18,20)(2,8,10,12,16,20)(2,8,10,12,18)(2,8,10,12,18,20)(2,8,10,12,20)(2,8,10,14)(2,8,10,14,16)(2,8,10,14,16,18)(2,8,10,14,16,18,20)(2,8,10,14,16,20)(2,8,10,14,18)(2,8,10,14,18,20)(2,8,10,14,20)(2,8,10,16)(2,8,10,16,18)(2,8,10,16,18,20)(2,8,10,16,20)(2,8,10,18)(2,8,10,18,20)(2,8,10,20)(2,8,12)(2,8,12,14)(2,8,12,14,16)(2,8,12,14,16,18)(2,8,12,14,16,18,20)(2,8,12,14,16,20)(2,8,12,14,18)(2,8,12,14,18,20)(2,8,12,14,20)(2,8,12,16)(2,8,12,16,18)(2,8,12,16,18,20)(2,8,12,16,20)(2,8,12,18)(2,8,12,18,20)(2,8,12,20)(2,8,14)(2,8,14,16)(2,8,14,16,18)(2,8,14,16,18,20)(2,8,14,16,20)(2,8,14,18)(2,8,14,18,20)(2,8,14,20)(2,8,16)(2,8,16,18)(2,8,16,18,20)(2,8,16,20)(2,8,18)(2,8,18,20)(2,8,20)(2,10)(2,10,12)(2,10,12,14)(2,10,12,14,16)(2,10,12,14,16,18)(2,10,12,14,16,18,20)(2,10,12,14,16,20)(2,10,12,14,18)(2,10,12,14,18,20)(2,10,12,14,20)(2,10,12,16)(2,10,12,16,18)(2,10,12,16,18,20)(2,10,12,16,20)(2,10,12,18)(2,10,12,18,20)(2,10,12,20)(2,10,14)(2,10,14,16)(2,10,14,16,18)(2,10,14,16,18,20)(2,10,14,16,20)(2,10,14,18)(2,10,14,18,20)(2,10,14,20)(2,10,16)(2,10,16,18)(2,10,16,18,20)(2,10,16,20)(2,10,18)(2,10,18,20)(2,10,20)(2,12)(2,12,14)(2,12,14,16)(2,12,14,16,18)(2,12,14,16,18,20)(2,12,14,16,20)(2,12,14,18)(2,12,14,18,20)(2,12,14,20)(2,12,16)(2,12,16,18)(2,12,16,18,20)(2,12,16,20)(2,12,18)(2,12,18,20)(2,12,20)(2,14)(2,14,16)(2,14,16,18)(2,14,16,18,20)(2,14,16,20)(2,14,18)(2,14,18,20)(2,14,20)(2,16)(2,16,18)(2,16,18,20)(2,16,20)(2,18)(2,18,20)(2,20)(4)(4,6)(4,6,8)(4,6,8,10)(4,6,8,10,12)(4,6,8,10,12,14)(4,6,8,10,12,14,16)(4,6,8,10,12,14,16,18)(4,6,8,10,12,14,16,18,20)(4,6,8,10,12,14,16,20)(4,6,8,10,12,14,18)(4,6,8,10,12,14,18,20)(4,6,8,10,12,14,20)(4,6,8,10,12,16)(4,6,8,10,12,16,18)(4,6,8,10,12,16,18,20)(4,6,8,10,12,16,20)(4,6,8,10,12,18)(4,6,8,10,12,18,20)(4,6,8,10,12,20)(4,6,8,10,14)(4,6,8,10,14,16)(4,6,8,10,14,16,18)(4,6,8,10,14,16,18,20)(4,6,8,10,14,16,20)(4,6,8,10,14,18)(4,6,8,10,14,18,20)(4,6,8,10,14,20)(4,6,8,10,16)(4,6,8,10,16,18)(4,6,8,10,16,18,20)(4,6,8,10,16,20)(4,6,8,10,18)(4,6,8,10,18,20)(4,6,8,10,20)(4,6,8,12)(4,6,8,12,14)(4,6,8,12,14,16)(4,6,8,12,14,16,18)(4,6,8,12,14,16,18,20)(4,6,8,12,14,16,20)(4,6,8,12,14,18)(4,6,8,12,14,18,20)(4,6,8,12,14,20)(4,6,8,12,16)(4,6,8,12,16,18)(4,6,8,12,16,18,20)(4,6,8,12,16,20)(4,6,8,12,18)(4,6,8,12,18,20)(4,6,8,12,20)(4,6,8,14)(4,6,8,14,16)(4,6,8,14,16,18)(4,6,8,14,16,18,20)(4,6,8,14,16,20)(4,6,8,14,18)(4,6,8,14,18,20)(4,6,8,14,20)(4,6,8,16)(4,6,8,16,18)(4,6,8,16,18,20)(4,6,8,16,20)(4,6,8,18)(4,6,8,18,20)(4,6,8,20)(4,6,10)(4,6,10,12)(4,6,10,12,14)(4,6,10,12,14,16)(4,6,10,12,14,16,18)(4,6,10,12,14,16,18,20)(4,6,10,12,14,16,20)(4,6,10,12,14,18)(4,6,10,12,14,18,20)(4,6,10,12,14,20)(4,6,10,12,16)(4,6,10,12,16,18)(4,6,10,12,16,18,20)(4,6,10,12,16,20)(4,6,10,12,18)(4,6,10,12,18,20)(4,6,10,12,20)(4,6,10,14)(4,6,10,14,16)(4,6,10,14,16,18)(4,6,10,14,16,18,20)(4,6,10,14,16,20)(4,6,10,14,18)(4,6,10,14,18,20)(4,6,10,14,20)(4,6,10,16)(4,6,10,16,18)(4,6,10,16,18,20)(4,6,10,16,20)(4,6,10,18)(4,6,10,18,20)(4,6,10,20)(4,6,12)(4,6,12,14)(4,6,12,14,16)(4,6,12,14,16,18)(4,6,12,14,16,18,20)(4,6,12,14,16,20)(4,6,12,14,18)(4,6,12,14,18,20)(4,6,12,14,20)(4,6,12,16)(4,6,12,16,18)(4,6,12,16,18,20)(4,6,12,16,20)(4,6,12,18)(4,6,12,18,20)(4,6,12,20)(4,6,14)(4,6,14,16)(4,6,14,16,18)(4,6,14,16,18,20)(4,6,14,16,20)(4,6,14,18)(4,6,14,18,20)(4,6,14,20)(4,6,16)(4,6,16,18)(4,6,16,18,20)(4,6,16,20)(4,6,18)(4,6,18,20)(4,6,20)(4,8)(4,8,10)(4,8,10,12)(4,8,10,12,14)(4,8,10,12,14,16)(4,8,10,12,14,16,18)(4,8,10,12,14,16,18,20)(4,8,10,12,14,16,20)(4,8,10,12,14,18)(4,8,10,12,14,18,20)(4,8,10,12,14,20)(4,8,10,12,16)(4,8,10,12,16,18)(4,8,10,12,16,18,20)(4,8,10,12,16,20)(4,8,10,12,18)(4,8,10,12,18,20)(4,8,10,12,20)(4,8,10,14)(4,8,10,14,16)(4,8,10,14,16,18)(4,8,10,14,16,18,20)(4,8,10,14,16,20)(4,8,10,14,18)(4,8,10,14,18,20)(4,8,10,14,20)(4,8,10,16)(4,8,10,16,18)(4,8,10,16,18,20)(4,8,10,16,20)(4,8,10,18)(4,8,10,18,20)(4,8,10,20)(4,8,12)(4,8,12,14)(4,8,12,14,16)(4,8,12,14,16,18)(4,8,12,14,16,18,20)(4,8,12,14,16,20)(4,8,12,14,18)(4,8,12,14,18,20)(4,8,12,14,20)(4,8,12,16)(4,8,12,16,18)(4,8,12,16,18,20)(4,8,12,16,20)(4,8,12,18)(4,8,12,18,20)(4,8,12,20)(4,8,14)(4,8,14,16)(4,8,14,16,18)(4,8,14,16,18,20)(4,8,14,16,20)(4,8,14,18)(4,8,14,18,20)(4,8,14,20)(4,8,16)(4,8,16,18)(4,8,16,18,20)(4,8,16,20)(4,8,18)(4,8,18,20)(4,8,20)(4,10)(4,10,12)(4,10,12,14)(4,10,12,14,16)(4,10,12,14,16,18)(4,10,12,14,16,18,20)(4,10,12,14,16,20)(4,10,12,14,18)(4,10,12,14,18,20)(4,10,12,14,20)(4,10,12,16)(4,10,12,16,18)(4,10,12,16,18,20)(4,10,12,16,20)(4,10,12,18)(4,10,12,18,20)(4,10,12,20)(4,10,14)(4,10,14,16)(4,10,14,16,18)(4,10,14,16,18,20)(4,10,14,16,20)(4,10,14,18)(4,10,14,18,20)(4,10,14,20)(4,10,16)(4,10,16,18)(4,10,16,18,20)(4,10,16,20)(4,10,18)(4,10,18,20)(4,10,20)(4,12)(4,12,14)(4,12,14,16)(4,12,14,16,18)(4,12,14,16,18,20)(4,12,14,16,20)(4,12,14,18)(4,12,14,18,20)(4,12,14,20)(4,12,16)(4,12,16,18)(4,12,16,18,20)(4,12,16,20)(4,12,18)(4,12,18,20)(4,12,20)(4,14)(4,14,16)(4,14,16,18)(4,14,16,18,20)(4,14,16,20)(4,14,18)(4,14,18,20)(4,14,20)(4,16)(4,16,18)(4,16,18,20)(4,16,20)(4,18)(4,18,20)(4,20)(6)(6,8)(6,8,10)(6,8,10,12)(6,8,10,12,14)(6,8,10,12,14,16)(6,8,10,12,14,16,18)(6,8,10,12,14,16,18,20)(6,8,10,12,14,16,20)(6,8,10,12,14,18)(6,8,10,12,14,18,20)(6,8,10,12,14,20)(6,8,10,12,16)(6,8,10,12,16,18)(6,8,10,12,16,18,20)(6,8,10,12,16,20)(6,8,10,12,18)(6,8,10,12,18,20)(6,8,10,12,20)(6,8,10,14)(6,8,10,14,16)(6,8,10,14,16,18)(6,8,10,14,16,18,20)(6,8,10,14,16,20)(6,8,10,14,18)(6,8,10,14,18,20)(6,8,10,14,20)(6,8,10,16)(6,8,10,16,18)(6,8,10,16,18,20)(6,8,10,16,20)(6,8,10,18)(6,8,10,18,20)(6,8,10,20)(6,8,12)(6,8,12,14)(6,8,12,14,16)(6,8,12,14,16,18)(6,8,12,14,16,18,20)(6,8,12,14,16,20)(6,8,12,14,18)(6,8,12,14,18,20)(6,8,12,14,20)(6,8,12,16)(6,8,12,16,18)(6,8,12,16,18,20)(6,8,12,16,20)(6,8,12,18)(6,8,12,18,20)(6,8,12,20)(6,8,14)(6,8,14,16)(6,8,14,16,18)(6,8,14,16,18,20)(6,8,14,16,20)(6,8,14,18)(6,8,14,18,20)(6,8,14,20)(6,8,16)(6,8,16,18)(6,8,16,18,20)(6,8,16,20)(6,8,18)(6,8,18,20)(6,8,20)(6,10)(6,10,12)(6,10,12,14)(6,10,12,14,16)(6,10,12,14,16,18)(6,10,12,14,16,18,20)(6,10,12,14,16,20)(6,10,12,14,18)(6,10,12,14,18,20)(6,10,12,14,20)(6,10,12,16)(6,10,12,16,18)(6,10,12,16,18,20)(6,10,12,16,20)(6,10,12,18)(6,10,12,18,20)(6,10,12,20)(6,10,14)(6,10,14,16)(6,10,14,16,18)(6,10,14,16,18,20)(6,10,14,16,20)(6,10,14,18)(6,10,14,18,20)(6,10,14,20)(6,10,16)(6,10,16,18)(6,10,16,18,20)(6,10,16,20)(6,10,18)(6,10,18,20)(6,10,20)(6,12)(6,12,14)(6,12,14,16)(6,12,14,16,18)(6,12,14,16,18,20)(6,12,14,16,20)(6,12,14,18)(6,12,14,18,20)(6,12,14,20)(6,12,16)(6,12,16,18)(6,12,16,18,20)(6,12,16,20)(6,12,18)(6,12,18,20)(6,12,20)(6,14)(6,14,16)(6,14,16,18)(6,14,16,18,20)(6,14,16,20)(6,14,18)(6,14,18,20)(6,14,20)(6,16)(6,16,18)(6,16,18,20)(6,16,20)(6,18)(6,18,20)(6,20)(8)(8,10)(8,10,12)(8,10,12,14)(8,10,12,14,16)(8,10,12,14,16,18)(8,10,12,14,16,18,20)(8,10,12,14,16,20)(8,10,12,14,18)(8,10,12,14,18,20)(8,10,12,14,20)(8,10,12,16)(8,10,12,16,18)(8,10,12,16,18,20)(8,10,12,16,20)(8,10,12,18)(8,10,12,18,20)(8,10,12,20)(8,10,14)(8,10,14,16)(8,10,14,16,18)(8,10,14,16,18,20)(8,10,14,16,20)(8,10,14,18)(8,10,14,18,20)(8,10,14,20)(8,10,16)(8,10,16,18)(8,10,16,18,20)(8,10,16,20)(8,10,18)(8,10,18,20)(8,10,20)(8,12)(8,12,14)(8,12,14,16)(8,12,14,16,18)(8,12,14,16,18,20)(8,12,14,16,20)(8,12,14,18)(8,12,14,18,20)(8,12,14,20)(8,12,16)(8,12,16,18)(8,12,16,18,20)(8,12,16,20)(8,12,18)(8,12,18,20)(8,12,20)(8,14)(8,14,16)(8,14,16,18)(8,14,16,18,20)(8,14,16,20)(8,14,18)(8,14,18,20)(8,14,20)(8,16)(8,16,18)(8,16,18,20)(8,16,20)(8,18)(8,18,20)(8,20)(10)(10,12)(10,12,14)(10,12,14,16)(10,12,14,16,18)(10,12,14,16,18,20)(10,12,14,16,20)(10,12,14,18)(10,12,14,18,20)(10,12,14,20)(10,12,16)(10,12,16,18)(10,12,16,18,20)(10,12,16,20)(10,12,18)(10,12,18,20)(10,12,20)(10,14)(10,14,16)(10,14,16,18)(10,14,16,18,20)(10,14,16,20)(10,14,18)(10,14,18,20)(10,14,20)(10,16)(10,16,18)(10,16,18,20)(10,16,20)(10,18)(10,18,20)(10,20)(12)(12,14)(12,14,16)(12,14,16,18)(12,14,16,18,20)(12,14,16,20)(12,14,18)(12,14,18,20)(12,14,20)(12,16)(12,16,18)(12,16,18,20)(12,16,20)(12,18)(12,18,20)(12,20)(14)(14,16)(14,16,18)(14,16,18,20)(14,16,20)(14,18)(14,18,20)(14,20)(16)(16,18)(16,18,20)(16,20)(18)(18,20)(20)()
Since number of elements in the set can go upto 10^5 and hence the size of the set will go upto 2^(10^5) which is huge. You can just either print it or if you want to store it , store it in a file.
It is not possible, as you pointed out yourself power set contains pow(2, size) no of elements. You need to print the entire set that can only be done by generating the set using backtracking, there is nothing better. To find sum of all subsets of a given set is however a simpler problem. If the no of elements is n, then each element in the array occurs 2^(n-1) times in the power set. Pseudo code : int sum = 0; for(int i = 0;i < n;i++){ sum += ( set[i] * ( 1 << (n-1) ) ); //pow(2, n-1) == 1 << (n-1) } cout << sum << endl; You would need a Big Integer Library for larger values of n.
I tried coding my own simple moving average in C++
I want a function that works. I believe my logic is correct, thus my (vector out of range error) must be coming from the lack of familiarity and using the code correctly. I do know that there is long code out there for this fairly simple algorithm. Please help if you can. Basically, I take the length as the "moving" window as it loops through j to the end of the size of the vector. This vector is filled with stock prices. If the length equaled 2 for a 2 day moving average for numbers 1 2 3 4. I should be able to output 1.5, 2.5, and 3.5. However, I get an out of range error. The logic is shown in the code. If an expert could help me with this simple moving average function that I am trying to create that would be great! Thanks. void Analysis::SMA() { double length; cout << "Enter number days for your Simple Moving Average:" << endl; cin >> length; double sum = 0; double a; while (length >= 2){ vector<double>::iterator it; for (int j = 0; j < close.size(); j++){ sum = vector1[length + j - 1] + vector1[length + j - 2]; a = sum / length; vector2.push_back(a); vector<double>::iterator g; for (g = vector2.begin(); g != vector2.end(); ++g){ cout << "Your SMA: " << *g; } } } }
You don't need 3 loops to calculate a moving average over an array of data, you only need 1. You iterate over the array and keep track of the sum of the last n items, and then just adjust it for each new value, adding one value and removing one each time. For example suppose you have a data set: 4 8 1 6 9 and you want to calculate a moving average with a window size of 3, then you keep a running total like this: iteration add subtract running-total output average 0 4 - 4 - (not enough values yet) 1 8 - 12 - 2 1 - 13 13 / 3 3 6 4 15 15 / 3 4 9 8 16 16 / 3 Notice that we add each time, we start subtracting at iteration 3 (for a window size of 3) and start outputting the average at iteration 2 (window size minus 1). So the code will be something like this: double runningTotal = 0.0; int windowSize = 3; for(int i = 0; i < length; i++) { runningTotal += array[i]; // add if(i >= windowSize) runningTotal -= array[i - windowSize]; // subtract if(i >= (windowSize - 1)) // output moving average cout << "Your SMA: " << runningTotal / (double)windowSize; } You can adapt this to use your vector data structure.
Within your outermost while loop you never change length so your function will run forever. Then, notice that if length is two and closes.size() is four, length + j - 1 will be 5, so my psychic debugging skills tell me your vector1 is too short and you index off the end.
This question has been answered but I thought I'd post complete code for people in the future seeking information. #include <iostream> #include <vector> using namespace std; int main() { vector<double> vector1 { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 }; double length; cout << "Enter number days for your Simple Moving Average:" << endl; cin >> length; double sum = 0; int cnt = 0; for (int i = 0; i < vector1.size(); i++) { sum += vector1[i]; cnt++; if (cnt >= length) { cout << "Your SMA: " << (sum / (double) length) << endl; sum -= vector1[cnt - length]; } } return 0; } This is slightly different than the answer. A 'cnt' variable in introduced to avoid an additional if statement.
Retrieval of items from a knapsack using dynamic programming
I'm new to dynamic programming and have tried my first DP problem. The problem statement is Given a knapsack of size C, and n items of sizes s[] with values v[], maximize the capacity of the items which can be put in the knapsack. An item may be repeated any number of times. (Duplicate items are allowed). Although I was able to formulate the recurrence relation and create the DP table, and eventually get the maximum value that can be put in the knapsack, I am not able to device a method to retrieve which values have to be selected to get the required sum. Here is my solution: #include <iostream> #include <cstdlib> #include <algorithm> #include <vector> using namespace std; int main() { int s[] = { 1, 3, 4, 5, 2, 7, 8 , 10}; int v[] = { 34, 45, 23, 78, 33, 5, 7 , 1}; int n = ( (sizeof(s)) / (sizeof(s[0])) ); vector<int> backtrack; int C = 15; int pos; int m[20]; m[0] = 0; int mx = 0; for ( int j = 1; j <= C; j++) { mx = 0; m[j] = m[j-1]; pos = j-1; for ( int i = 0; i < n; i++) { mx = m[i-s[i]] + v[i]; if ( mx > m[i] ) { m[i] = mx; pos = i - s[j]; } } backtrack.push_back(pos); } cout << m[C] << endl<<endl; for ( int i = 0; i < backtrack.size(); i++) { cout << s[backtrack[i]] <<endl; } return 0; } In my solution, I've attempted to store the positions of the maximum value item selcted in a vector, and eventually print them. However this does not seem to give me the correct solution. Running the program produces: 79 2 3 0 5 2 7 8 10 34 45 23 78 33 5 7 It is obvious from the output that the numbers in the output cant be the sizes of the items selected as there there no item of size 0 as shown in the output. I hope that you will help me find the error in my logic or implementation. Thanks.
You are following the greedy approach. It's pretty clever , but it is heuristic. I will not give you the correct code, as it might be a homework, but the recursive function knapsack would look like this: knapsack(C): maximum profit achivable using a knapsack of Capacity C knapsack(C) = max { knapsack(C-w[i]) + v[i] } for all w[i] <= C knapsack(0) = 0 In code: dp(0) = 0; for i = 1 to C dp(i) = -INF; for k = i-1 downto 0 if w[k] < i then dp(i) = max{dp(i-w[k]) + v[k], dp(i)}; print dp(Capacity);