2021-07-02 22:40:04 +08:00
|
|
|
/**
|
|
|
|
* @file
|
|
|
|
* @brief Implementation of [House Robber Problem] algorithm
|
|
|
|
* @details
|
2021-07-04 11:13:12 +08:00
|
|
|
* Solution of House robber problem uses a dynamic programming concept that
|
|
|
|
* works in \f$O(n)\f$ time and works in \f$O(1)\f$ space.
|
2021-07-07 10:51:23 +08:00
|
|
|
* @author [Swastika Gupta](https://github.com/Swastyy)
|
2021-07-02 22:40:04 +08:00
|
|
|
*/
|
|
|
|
|
2021-07-04 11:02:49 +08:00
|
|
|
#include <cassert> /// for assert
|
2021-07-04 18:30:13 +08:00
|
|
|
#include <climits> /// for std::max
|
2021-07-04 11:02:49 +08:00
|
|
|
#include <iostream> /// for io operations
|
|
|
|
#include <vector> /// for std::vector
|
2021-07-02 22:40:04 +08:00
|
|
|
/**
|
|
|
|
* @namespace dynamic_programming
|
|
|
|
* @brief House robber algorithm
|
|
|
|
*/
|
|
|
|
namespace dynamic_programming {
|
|
|
|
/**
|
|
|
|
* @namespace house_robber
|
|
|
|
* @brief Functions for House Robber algorithm
|
|
|
|
*/
|
|
|
|
namespace house_robber {
|
|
|
|
/**
|
2021-07-04 11:13:12 +08:00
|
|
|
* @brief The main function implements house robber algorithm using dynamic
|
|
|
|
* programming
|
2021-07-02 22:40:04 +08:00
|
|
|
* @param money array containing money in the ith house
|
|
|
|
* @param n size of array
|
|
|
|
* @returns maximum amount of money that can be robbed
|
|
|
|
*/
|
|
|
|
std::uint64_t houseRobber(const std::vector<int> &money, int n) {
|
2021-07-04 11:02:49 +08:00
|
|
|
if (n == 0) { // if there is no house
|
|
|
|
return 0;
|
2021-07-02 22:40:04 +08:00
|
|
|
}
|
2021-07-04 11:02:49 +08:00
|
|
|
if (n == 1) { // if there is only one house
|
2021-07-02 22:40:04 +08:00
|
|
|
return money[0];
|
|
|
|
}
|
2021-07-04 11:13:12 +08:00
|
|
|
if (n == 2) { // if there are two houses, one with the maximum amount of
|
|
|
|
// money will be robbed
|
2021-07-04 11:09:32 +08:00
|
|
|
return std::max(money[0], money[1]);
|
2021-07-04 11:02:49 +08:00
|
|
|
}
|
|
|
|
int max_value = 0; // contains maximum stolen value at the end
|
2021-07-02 22:40:04 +08:00
|
|
|
int value1 = money[0];
|
2021-07-04 11:09:32 +08:00
|
|
|
int value2 = std::max(money[0], money[1]);
|
2021-07-04 11:02:49 +08:00
|
|
|
for (int i = 2; i < n; i++) {
|
2021-07-04 11:09:32 +08:00
|
|
|
max_value = std::max(money[i] + value1, value2);
|
2021-07-04 11:02:49 +08:00
|
|
|
value1 = value2;
|
|
|
|
value2 = max_value;
|
2021-07-02 22:40:04 +08:00
|
|
|
}
|
2021-07-04 11:02:49 +08:00
|
|
|
|
2021-07-02 22:40:04 +08:00
|
|
|
return max_value;
|
|
|
|
}
|
|
|
|
} // namespace house_robber
|
|
|
|
} // namespace dynamic_programming
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Test implementations
|
|
|
|
* @returns void
|
|
|
|
*/
|
|
|
|
static void test() {
|
2021-07-04 11:02:49 +08:00
|
|
|
// Test 1
|
2021-07-02 22:40:04 +08:00
|
|
|
// [1, 2, 3, 1] return 4
|
|
|
|
std::vector<int> array1 = {1, 2, 3, 1};
|
|
|
|
std::cout << "Test 1... ";
|
2021-07-04 11:13:12 +08:00
|
|
|
assert(
|
|
|
|
dynamic_programming::house_robber::houseRobber(array1, array1.size()) ==
|
|
|
|
4); // here the two non-adjacent houses that are robbed are first and
|
|
|
|
// third with total sum money as 4
|
2021-07-02 22:40:04 +08:00
|
|
|
std::cout << "passed" << std::endl;
|
|
|
|
|
2021-07-04 11:02:00 +08:00
|
|
|
// Test 2
|
2021-07-02 22:40:04 +08:00
|
|
|
// [6, 7, 1, 3, 8, 2, 4] return 19
|
|
|
|
std::vector<int> array2 = {6, 7, 1, 3, 8, 2, 4};
|
|
|
|
std::cout << "Test 2... ";
|
2021-07-04 11:13:12 +08:00
|
|
|
assert(
|
|
|
|
dynamic_programming::house_robber::houseRobber(array2, array2.size()) ==
|
|
|
|
19); // here the four non-adjacent houses that are robbed are first,
|
|
|
|
// third, fifth and seventh with total sum money as 19
|
2021-07-02 22:40:04 +08:00
|
|
|
std::cout << "passed" << std::endl;
|
2021-07-04 11:13:12 +08:00
|
|
|
|
2021-07-04 11:12:34 +08:00
|
|
|
// Test 3
|
2021-07-02 22:40:04 +08:00
|
|
|
// [] return 0
|
|
|
|
std::vector<int> array3 = {};
|
|
|
|
std::cout << "Test 3... ";
|
2021-07-04 11:13:12 +08:00
|
|
|
assert(
|
|
|
|
dynamic_programming::house_robber::houseRobber(array3, array3.size()) ==
|
|
|
|
0); // since there is no house no money can be robbed
|
2021-07-02 22:40:04 +08:00
|
|
|
std::cout << "passed" << std::endl;
|
|
|
|
|
2021-07-04 11:12:34 +08:00
|
|
|
// Test 4
|
2021-07-02 22:40:04 +08:00
|
|
|
// [2,7,9,3,1] return 12
|
2021-07-04 11:02:49 +08:00
|
|
|
std::vector<int> array4 = {2, 7, 9, 3, 1};
|
2021-07-02 22:40:04 +08:00
|
|
|
std::cout << "Test 4... ";
|
2021-07-04 11:13:12 +08:00
|
|
|
assert(
|
|
|
|
dynamic_programming::house_robber::houseRobber(array4, array4.size()) ==
|
|
|
|
12); // here the three non-adjacent houses that are robbed are first,
|
|
|
|
// third and fifth with total sum money as 12
|
2021-07-02 22:40:04 +08:00
|
|
|
std::cout << "passed" << std::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Main function
|
|
|
|
* @returns 0 on exit
|
|
|
|
*/
|
|
|
|
int main() {
|
|
|
|
test(); // execute the test
|
|
|
|
return 0;
|
|
|
|
}
|