Files
C-Plus-Plus/dynamic_programming/partition_problem.cpp
realstealthninja 0d766b0f8a feat: update to CXX standard 17 and add CMakeLists file to directories without them (#2746)
* chore: add cache and build comment to git ignore

* fix: add cmakelists to dynamic programming

* fix: add cmakelists to greedy_algorithms

* fix: add cmakelists to operations_on_datastructures

* fix: add cmakelists to range_queries

* fix: add `dynamic_programmin`, `greedy_algorithms`, `range_queries` and `operations_on_datastructures` subdirectories to cmakelists.txt

* fix: init of transform_reduce in dynamic_programming

* fix: add an include for functional in catalan_numbers

* chore: bump CXX standard to 20

* revert: bump CXX standard to 20

* chore: bump c++ version to 17 and add justification

Arm supports c++ 17
Esp32 supports c++ 23
decision was made to be 17 because it seemed to offer the best combatability

* fix: compilation error in catalan numbers

* fix: add <set> header to longest increasing subsequence nlogn

* fix: add cmath & algorithm header to mo.cpp

* fix: remove register key word from fast integer

* fix: replace using namespace std with std::cin and std::cout

* docs: typo in c++17

* fix: memory leak in bellman_ford

* fix: typo in bellman_ford

* fix: typo in word_break

* fix: dynamic array in coin_change

* fix dynamic array in egg_dropping puzzle

* chore: remove unnecessary comment

* fix: add vla to be an error

* chore: add extra warnings

* fix: use add_compile options instead of set()

* fix: compile options are not strings

* fix: vla in floyd_warshall

* fix: vla in egg_dropping_puzzel

* fix: vla in coin_change

* fix: vla in edit_distance

* fix: vla in floyd_warshall

* feat: remove kadane and replace it with kadane2

* fix: vla in longest_common_subsequence

* fix: int overflow in floyd_warshall

* fix: vla in lisnlogn

* fix: use const vector& instead of array

* fix: use dynamic array instead of vla in knapsack

* fix: use of and in msvc is unsupported by default adding permissive flag fixes it

* test: make executables the tests themselves

* Revert "test: make executables the tests themselves"

This reverts commit 7a16c31c4e.

* fix: make dist constant in print

* fix: namespace issue in unbounded_0_1

* fix: include cstdint to fix compilation
2024-11-04 18:00:20 +05:30

107 lines
4.2 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/******************************************************************************
* @file
* @brief Implementation of the [Partition
* Problem](https://en.wikipedia.org/wiki/Partition_problem )
* @details
* The partition problem, or number partitioning, is the task of deciding
* whether a given multiset S of positive integers can be partitioned into two
* subsets S1 and S2 such that the sum of the numbers in S1 equals the sum of
* the numbers in S2. Although the partition problem is NP-complete, there is a
* pseudo-polynomial time dynamic programming solution, and there are heuristics
* that solve the problem in many instances, either optimally or approximately.
* For this reason, it has been called "the easiest hard problem".
*
* The worst case time complexity of Jarviss Algorithm is O(n^2). Using
* Grahams scan algorithm, we can find Convex Hull in O(nLogn) time.
*
* ### Implementation
*
* Step 1
* Calculate sum of the array. If sum is odd, there can not be two subsets with
* equal sum, so return false.
*
* Step 2
* If sum of array elements is even, calculate sum/2 and find a subset of array
* with sum equal to sum/2.
*
* @author [Lajat Manekar](https://github.com/Lazeeez)
*
*******************************************************************************/
#include <cassert> /// for assert
#include <cstdint> /// for std::uint64_t
#include <iostream> /// for IO Operations
#include <numeric> /// for std::accumulate
#include <vector> /// for std::vector
/******************************************************************************
* @namespace dp
* @brief Dynamic programming algorithms
*******************************************************************************/
namespace dp {
/******************************************************************************
* @namespace partitionProblem
* @brief Partition problem algorithm
*******************************************************************************/
namespace partitionProblem {
/******************************************************************************
* @brief Returns true if arr can be partitioned in two subsets of equal sum,
* otherwise false
* @param arr vector containing elements
* @param size Size of the vector.
* @returns @param bool whether the vector can be partitioned or not.
*******************************************************************************/
bool findPartiion(const std::vector<uint64_t> &arr, uint64_t size) {
uint64_t sum = std::accumulate(arr.begin(), arr.end(),
0); // Calculate sum of all elements
if (sum % 2 != 0) {
return false; // if sum is odd, it cannot be divided into two equal sum
}
std::vector<bool> part;
// bool part[sum / 2 + 1];
// Initialize the part array as 0
for (uint64_t it = 0; it <= sum / 2; ++it) {
part.push_back(false);
}
// Fill the partition table in bottom up manner
for (uint64_t it = 0; it < size; ++it) {
// The element to be included in the sum cannot be greater than the sum
for (uint64_t it2 = sum / 2; it2 >= arr[it];
--it2) { // Check if sum - arr[i]
// ould be formed from a subset using elements before index i
if (part[it2 - arr[it]] == 1 || it2 == arr[it]) {
part[it2] = true;
}
}
}
return part[sum / 2];
}
} // namespace partitionProblem
} // namespace dp
/*******************************************************************************
* @brief Self-test implementations
* @returns void
*******************************************************************************/
static void test() {
std::vector<uint64_t> arr = {{1, 3, 3, 2, 3, 2}};
uint64_t n = arr.size();
bool expected_result = true;
bool derived_result = dp::partitionProblem::findPartiion(arr, n);
std::cout << "1st test: ";
assert(expected_result == derived_result);
std::cout << "Passed!" << std::endl;
}
/*******************************************************************************
* @brief Main function
* @returns 0 on exit
*******************************************************************************/
int main() {
test(); // run self-test implementations
return 0;
}