Written by @Yusif_M and @Tuncay_Pashayev.
You have coins and you should make different values with using these coins. In the next line you input n intengers - the value of your coins. For this problem we can use knapsack.
We use array for input the value of our coins. Let's call them a_0, a_1, a_2, ..., a_{n-1}. Then create another array called knapsack. The elements will be knapsack_0, knapsack_1, knapsack_2, ..., knapsack_{k-1}. In this case the intenger k is the maximum value that we can make with using our coins.
Let's explain knapsack. The maximum value that we can get is the sum of our coin's values:
= a_0 + a_1 + a_2 + ... + a_{n-1}
Our first element of array is a_0, if we can make value with using a_0, that means we can make another value with using a_1 and new value will be a_0 + a_1. If we can make value with using a_0 and a_1, that means we can make another value with using a_2. The new values will be:
a_0 + a_1 + a_2
a_0 + a_2
a_1 + a_2
It is going like that till we reach the maximum value - k. In the code we write like this:
#define MAX 100001
int knapsack[MAX];Creating an array called knapsack. The reason of defining MAX - is, the maximum value of a_i can get is and the maximum value n can get is . The product makes , indexing is starting from , so we add more, it makes elements for knapsack array.
int n,k = 0;
cin >> n;
int a[n];We create intenger - n and intenger - k, making and creating another array.
for (int i = 0; i < n; i++)
{
cin >> a[i];
k += a[i];
}Input array elements and finding maximum value with summing the value of our coins.
knapsack[0] = 1;
for (int i = 0; i < n; i++)
{
for (int j = k; j >= a[i]; j--)
{
if (knapsack[j - a[i]] == 1)
knapsack[j] = 1;
}
}First we need to give value to knapsack_0 otherwise all the elements of array - knapsack will be , so the answer will be wrong. Then we are checking if we were able to create a value using a_i, then we can create a new value with adding a_i to j-a_i to this will give us , so knapsack_j will be also.
int res = 0;
for (int i = 1; i <= k; i++)
{
if (knapsack[i] == 1)
res++;
}
cout << res << endl; New intenger called res and giving value . If we were able to create value increase the value of by one. is number of different values that we were able to create.
for (int i = 1; i < k; i++)
{
if (knapsack[i] == 1)
cout << i << ' ';
} Then output all the values that we were able to create.
#include <iostream>
using namespace std;
#define MAX 100001
int knapsack[MAX];
int main()
{
int n,k = 0;
cin >> n;
int a[n];
for (int i = 0; i < n; i++)
{
cin >> a[i];
k += a[i];
}
knapsack[0] = 1;
for (int i = 0; i < n; i++)
{
for (int j = k; j >= a[i]; j--)
{
if (knapsack[j - a[i]] == 1)
knapsack[j] = 1;
}
}
int res = 0;
for (int i = 1; i <= k; i++)
{
if (knapsack[i] == 1)
res++;
}
cout << res << endl;
for (int i = 1; i <= k; i++)
{
if (knapsack[i] == 1)
cout << i << ' ';
}
}Written by medv.
We need to determine which sums can be obtained by choosing some subset of the coins. Each coin can be:
not used;
used exactly once.
Therefore, this is a variant of the Knapsack problem.
Let the sum of all coins be S = x_1 + x_2 + ... + x_n. Since n \le 100 and x_i \le 1000, we have S \le 100000. This allows us to store information about every possible sum.
Define
Initially, we have not used any coins. The sum is always achievable, so dp[0] = 1. All other values are equal to zero. To speed up the solution, we'll store in a bitset.
For each coin with denomination x_i:
shift the bitset by x_i positions;
combine the result with the original bitset:
Count the number of set bits, excluding .
Then, iterate through all sums from to and print those for which dp[s] = 1.
Algorithm implementation
In the bitset , we'll store the array.
#define MAX 100010
bitset<MAX> mask;Read the number of coins . Set dp[0] = 1, since the sum can be obtained by using no coins.
scanf("%d", &n);
mask.set(0);In the variable , we calculate the sum of the denominations of all coins.
s = 0;Process all coins one by one in a loop.
for (i = 0; i < n; i++)
{Process the coin with denomination .
scanf("%d", &w);
s += w;
mask |= (mask << w);
}Return the number of set bits. However, the sum is always achievable, so it must be excluded.
printf("%d\n", mask.count() - 1);Print all achievable positive sums.
for (i = 1; i <= s; i++)
if (mask[i]) printf("%d ", i);
printf("\n");