Skip to content

Instantly share code, notes, and snippets.

@asauber
Last active August 29, 2015 14:12
Show Gist options
  • Save asauber/73309c05c725cf759cfa to your computer and use it in GitHub Desktop.
Save asauber/73309c05c725cf759cfa to your computer and use it in GitHub Desktop.
Dynamic Programming Example (C++)
/*
How many ways can the set of numbers from 1 to N be partitioned into two
subsets in such a way that the sum of both subsets is equal?
Hint 1. For each partitioning, the sum of each subset will be the same value
Hint 2. This value is the sum from 1 to N divided by 2. (N * (N + 1) / 2) / 2
Hint 3. The problem has been reduced to, "How many subsets of a given set sum
to a specific value?". Note that once we have this number of subsets, we
divide it by 2, because each subset is a member of pair that satisfies the
original question.
Hint 4. Start with a Dynamic Programming array that holds the number of subsets
that sum to values from 0 to T, where T is the target value as computed above.
The indicies of the array will be target sums and the values are the number
of subsets that sum to these values.
Hint 5. Add numbers to the set one at a time, updating the DP array with the
current count for each target
Hint 6. After adding all of the elements to the set the answer will be the
count for the target value
*/
// Solution
#include <iostream>
using namespace std;
long num_subsets_with_sum(int n, int target) {
long dp[target + 1];
for (int i = 0; i <= target; i++) {
dp[i] = 0;
}
dp[0] = 1;
for (int num = 1; num <= n; num++) {
for (int curr_target = target; curr_target >= num; curr_target--) {
dp[curr_target] += dp[curr_target - num];
}
}
return dp[target];
}
int main() {
int n;
cin >> n;
int series_sum = n * (n + 1) / 2;
if (series_sum % 2 == 1) {
cout << 0 << "\n";
return 0;
}
int target = series_sum / 2;
cout << num_subsets_with_sum(n, target) / 2 << "\n";
return 0;
}
/*
Example:
Given the set {1, 2, 3, 4, 5, 6, 7}, how many ways are there to produce the sum 14?
Technique:
Build up the set one element at a time, while updating a DP array
Number of ways to produce the sum:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 (initial DP array)
1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 (iteration 1: add 1 to the set)
1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 (iteration 2: add 2 to the set)
1 1 1 2 1 1 1 0 0 0 0 0 0 0 0 (iteration 3: add 3 to the set)
1 1 1 2 2 2 2 2 1 1 1 0 0 0 0 (iteration 4: add 4 to the set)
1 1 1 2 2 3 3 3 3 3 3 2 2 1 1 (iteration 5: add 5 to the set)
1 1 1 2 2 3 4 4 4 5 5 5 5 4 4 (iteration 6: add 6 to the set)
1 1 1 2 2 3 4 5 5 6 7 7 8 8 8 (iteration 7: add 7 to the set)
In each iteration, previous values of the DP array are used to calculate new values,
given the item being added to the set.
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment