From 92baff81df67c18a94951ff790372f22c9ac8ddf Mon Sep 17 00:00:00 2001 From: Lam Haoyin Date: Sat, 1 Jan 2022 13:08:06 +0800 Subject: [PATCH] add: 220101, I am vegetable --- 2201/220101.cpp | 95 +++++++++++++++++++++++++++++++++++++++++++++ 2201/CMakeLists.txt | 2 +- 2 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 2201/220101.cpp diff --git a/2201/220101.cpp b/2201/220101.cpp new file mode 100644 index 0000000..f2a2e10 --- /dev/null +++ b/2201/220101.cpp @@ -0,0 +1,95 @@ +#include +#include +#include +#include + +/** + * Usage of dynamic programming + * + * Initial attempt: + * try to merge 2 arrays which is calculated before. + * [3, 1, 7] => 49; [5, 8] => 48 + * [3, 1, 7, 5, 8] => 501 + * dp[L][R] <- max{merge(dp[L][L + i], dp[L + i + 1][R])} + * + * Why it fails: + * Since the solution might be in a completely shuffled + * order, making the previous results useless. + * + * How the solution solved it: + * The solution iterates from smaller intervals to + * larger intervals. + * dp[L][R] <- max{dp[L][L + i - 1] + dp[L + i + 1][R] + n[L + i] * n[L - 1] * n[R + 1]} + * + * Why solution works? + * In my previous attempt, There is no information such as + * *Which one is eliminated the first [Elimination Order]?* + * thus the order to eliminate remains unknown. + * The solution iterates *the last number to eliminate*, + * avoided to consider the order. (by brute force) + * + */ + +class Solution { +public: + static int maxCoins(const std::vector& nums) { + const auto n = nums.size(); + int num[n + 2]; + std::memcpy(num + 1, &nums[0], n * sizeof(int)); + num[0] = num[n + 1] = 1; + + int dp[n + 2][n + 2]; + std::memset(dp, 0, sizeof dp); + for (int i = 1; i <= n; ++i) + dp[i][i] = num[i - 1] * num[i] * num[i + 1]; + dp[0][0] = num[1]; + dp[n + 1][n + 1] = num[n]; + + for (int interval = 2; interval <= n; ++interval) + for (int L = 1, R = interval; R <= n; ++L, ++R) + for (int M = L; M <= R; ++M) + dp[L][R] = std::max(dp[L][R], dp[L][M - 1] + dp[M + 1][R] + num[M] * num[L - 1] * num[R + 1]); + + return dp[1][n]; + } +}; + +std::map, int> m; +int cnt = 0; + +int bruteForce(const std::vector& nums) { + if (m[nums]) { return m[nums]; } + ++cnt; + if (nums.size() == 1) + return nums[0]; + else if (nums.empty()) + return 0; + int ret = -1; + for (auto it = nums.begin(); it != nums.end(); ++it) { + std::vector d(nums.begin(), it); + d.insert(d.end(), it + 1, nums.end()); + int t = (*it * (it == nums.begin() ? 1 : *(it - 1)) * ((it + 1 == nums.end()) ? 1 : *(it + 1))) + bruteForce(d); + ret = (t > ret) ? t : ret; + } + return m[nums] = ret; +} + +int betterBruteForce(const std::vector& nums, int append) { + return 0; +} + +int main() { + // 3, 1, 5, 87, 9 --> 4101 + // 3, 1, 5, 87, 9, 51 --> 63102 + srand(time(nullptr)); + const int LIM = 15; + std::vector s; + s.reserve(LIM); + for (int i = 0; i < LIM; ++i) { + s.push_back(rand() % 100 + 1); + } + std::printf("%d\n", Solution::maxCoins(s)); + std::printf("%d\n", bruteForce(s)); + std::printf("Count = %d\n", cnt); + return 0; +} \ No newline at end of file diff --git a/2201/CMakeLists.txt b/2201/CMakeLists.txt index 5e425c3..b367a11 100644 --- a/2201/CMakeLists.txt +++ b/2201/CMakeLists.txt @@ -3,4 +3,4 @@ PROJECT(2201) SET(CMAKE_CXX_STANDARD 23) -ADD_EXECUTABLE(2201 220101-CN.cpp) \ No newline at end of file +ADD_EXECUTABLE(2201 220101.cpp) \ No newline at end of file