diff --git a/05- May/19- Is Graph Bipartite?/.gitkeep b/05- May/19- Is Graph Bipartite?/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/05- May/23- Kth Largest Element in a Stream/23- Kth Largest Element in a Stream (Lama Salah).cpp b/05- May/23- Kth Largest Element in a Stream/23- Kth Largest Element in a Stream (Lama Salah).cpp new file mode 100644 index 000000000..16e9f9eae --- /dev/null +++ b/05- May/23- Kth Largest Element in a Stream/23- Kth Largest Element in a Stream (Lama Salah).cpp @@ -0,0 +1,39 @@ +// Author: Lama Salah + +class KthLargest { + priority_queue, greater> pq; // Priority queue to store elements in sorted order. + int k; // Declares an integer variable k, representing the kth largest element. + +public: + // Constructor of the KthLargest class. + KthLargest(int k, vector& nums) { + // Initializes the priority queue pq as a min heap. + pq = priority_queue, greater>(); + this->k = k; // Assigns the value of k to the member variable k. + + // Iterate over each element in the vector nums. + for (auto& i : nums) + pq.push(i); // Push the current element into the priority queue pq. + + // Remove the smallest element from pq until its size becomes k. + while (pq.size() > k) + pq.pop(); + } + + // Add a new value to the KthLargest object. + int add(int val) { + pq.push(val); // Push the input value val into the priority queue pq. + + // If the size of pq is greater than k after adding the new value, remove the smallest element from pq. + if (pq.size() > k) pq.pop(); + + // Return the top element of pq, which represents the kth largest element. + return pq.top(); + } +}; + +/** + * Your KthLargest object will be instantiated and called as such: + * KthLargest* obj = new KthLargest(k, nums); + * int param_1 = obj->add(val); + */ \ No newline at end of file diff --git a/05- May/24- Maximum Subsequence Score/24- Maximum Subsequence Score (Ahmed Hossam).cpp b/05- May/24- Maximum Subsequence Score/24- Maximum Subsequence Score (Ahmed Hossam).cpp new file mode 100644 index 000000000..8ab8ec31a --- /dev/null +++ b/05- May/24- Maximum Subsequence Score/24- Maximum Subsequence Score (Ahmed Hossam).cpp @@ -0,0 +1,51 @@ +// Author: Ahmed Hossam + +class Solution { +public: + long long maxScore(vector& nums1, vector& nums2, int k) { + // Get the size of nums1 + int n = nums1.size(); + + // Create a vector of indices from 0 to n - 1 + vector < int > idx(n); + iota(idx.begin(), idx.end(), 0); + + // Sort the indices based on the corresponding values in nums2 + sort(idx.begin(), idx.end(), [&](int i, int j){ + return nums2[i] < nums2[j]; + }); + + // Create a min-heap priority queue + priority_queue < int, vector < int >, greater < int > > pq; + + // Variables to keep track of the current sum and maximum sequence + long long curr_sum = 0, max_seq = 0; + + // Lambda function to add an element to the current sum and the priority queue + auto add = [&](int x){ + curr_sum += x; + pq.push(x); + }; + + // Lambda function to remove the smallest element from the current sum and the priority queue + auto remove = [&](){ + curr_sum -= pq.top(); + pq.pop(); + }; + + // Iterate over the indices in reverse order + for(int i = n - 1; i >= 0; i--){ + // Add the corresponding element from nums1 to the current sum and the priority queue + add(nums1[idx[i]]); + + // If the size of the priority queue reaches k, update the maximum sequence and remove the smallest element + if(pq.size() == k){ + max_seq = max(max_seq, curr_sum * nums2[idx[i]]); + remove(); + } + } + + // Return the maximum sequence + return max_seq; + } +}; diff --git a/05- May/24- Maximum Subsequence Score/24- Maximum Subsequence Score (Mahmoud Aboelsoud).cpp b/05- May/24- Maximum Subsequence Score/24- Maximum Subsequence Score (Mahmoud Aboelsoud).cpp new file mode 100644 index 000000000..132b12678 --- /dev/null +++ b/05- May/24- Maximum Subsequence Score/24- Maximum Subsequence Score (Mahmoud Aboelsoud).cpp @@ -0,0 +1,52 @@ +// Author: Mahmoud Aboelsoud + +class Solution { +public: + long long maxScore(vector& nums1, vector& nums2, int k) { + // we need to find the maximum score subsequence of size of k + // we caclulate the score by selecting k indexes adn calculate the sum of them from nums1 adn multiply the sum by the minimum value of the selected indexes from nums2 + // we can use a greedy approach to select the k indexes + // we can store the values of nums1 and nums2 in a vector of pairs and sort them in a decreasing order based on the values of nums2 + // after sorting we will to make the second element of the pair as the minimum value of the selected indexes from nums2 + // and multipy it by the smmaion of the max sum of k elements from the first element of the pair in indeces smaller than or equal to i (the selected pos of the min second element of the pair) + + + // v: vector of pairs to store the values of nums1 and nums2 + vector> v; + + // store the values of nums1 and nums2 in v + for(int i = 0; i < nums1.size(); i++){ + v.emplace_back(nums1[i], nums2[i]); + } + + // sort v in a decreasing order based on the values of nums2 + sort(v.begin(), v.end(), [](pair&p1, pair&p2){ + if(p1.second == p2.second) return p1.first > p2.first; + + return p1.second > p2.second; + }); + + // pq: priority queue to store the first element of the pair in a decreasing order + priority_queue, greater> pq; + // sum: the sum of the max sum of k elements from the first element of the pair in indeces smaller than or equal to i (the selected pos of the min second element of the pair) + // ans: the answer + long long sum = 0, ans = 0; + + for(int i = 0; i < v.size(); i++){ + // add the first element of the pair to the sum and push it to the priority queue + sum += v[i].first; + pq.push(v[i].first); + + // if the size of pq is equal to k, update the answer by the max of the current answer and the sum multiplied by the second element of the pair + if(pq.size() == k){ + ans = max(ans, sum * v[i].second); + // subtract the top element of the priority queue from the sum + sum -= pq.top(); + pq.pop(); + } + } + + // return the answer + return ans; + } +}; diff --git a/05- May/24- Maximum Subsequence Score/24- Maximum Subsequence Score (Mina Magdy).cpp b/05- May/24- Maximum Subsequence Score/24- Maximum Subsequence Score (Mina Magdy).cpp new file mode 100644 index 000000000..8faf18722 --- /dev/null +++ b/05- May/24- Maximum Subsequence Score/24- Maximum Subsequence Score (Mina Magdy).cpp @@ -0,0 +1,42 @@ +// Author: Mina Magdy + +class Solution { +public: + long long maxScore(vector& nums1, vector& nums2, int k) { + int n = nums1.size(); // Number of elements in nums1 + vector idx(n); // Vector to store indices of nums1 + iota(idx.begin(), idx.end(), 0); // Initialize idx with indices from 0 to n-1 + sort(idx.begin(), idx.end(), [&](auto &a, auto &b) { + return nums1[a] < nums1[b]; // Sort idx based on the values of nums1 in ascending order + }); + vector> vec; + for (int k = 0; k < n; k++) { + vec.emplace_back(nums2[idx[k]], k); // Create a vector of pairs (nums2 value, corresponding idx[k]) + } + sort(vec.begin(), vec.end()); // Sort vec in ascending order based on nums2 values + int j = n - 1; // Pointer for iterating nums1 in reverse order + int cnt = 0; // Counter for the number of elements chosen + long long sum = 0, mx = 0; // sum: sum of chosen nums1 values, mx: maximum score + set removedIndices; // Set to keep track of removed indices + for (int v = 0; v < n; v++) { + auto &[vl, id] = vec[v]; // vl: nums2 value, id: corresponding idx[k] + removedIndices.insert(idx[id]); // Add the corresponding idx to removedIndices set + if (id > j) { + cnt--; // Decrement the counter if id is greater than j + sum -= nums1[idx[id]]; // Subtract the value at idx[id] from the sum + } + while (cnt < k - 1 && j >= 0) { + if (removedIndices.count(idx[j])) { // Skip the index if it is already removed + j--; + continue; + } + cnt++; // Increment the counter + sum += nums1[idx[j--]]; // Add the value at idx[j] to the sum and move the pointer j backwards + } + if (cnt == k - 1) { + mx = max(mx, (sum + nums1[idx[id]]) * vl); // Calculate the score and update mx if it's greater + } + } + return mx; // Return the maximum score + } +}; diff --git a/05- May/24- Maximum Subsequence Score/24- Maximum Subsequence Score (Noura Algohary).cpp b/05- May/24- Maximum Subsequence Score/24- Maximum Subsequence Score (Noura Algohary).cpp new file mode 100644 index 000000000..1763fff1c --- /dev/null +++ b/05- May/24- Maximum Subsequence Score/24- Maximum Subsequence Score (Noura Algohary).cpp @@ -0,0 +1,59 @@ +// Author: Noura Algohary +class Solution { +public: + void sort2Vectors(vector& vec1, vector& vec2, int n) +{ + pair pairt[n]; + + // Storing the respective array + // elements in pairs. + for (int i = 0; i < n; i++) + { + pairt[i].first = vec2[i]; + pairt[i].second = vec1[i]; + } + + // Sorting the pair array. + sort(pairt, pairt + n); + + // Modifying original vectors + for (int i = 0; i < n; i++) + { + vec2[i] = pairt[i].first; + vec1[i] = pairt[i].second; + } +} + long long maxScore(vector& nums1, vector& nums2, int k) { + priority_queue pq; + long long maxProduct = 0, subSum = 0; + int n = nums2.size(); + + // sort two vectors according to the second one + sort2Vectors(nums1, nums2, n); + + // start with the + for(int i =n-1 ; i> n-k; i--) + { + subSum += nums1[i]; + // negative sign to store nums in ascending order + pq.push(-nums1[i]); + } + + for(int i = n-k; i>=0; i--) + { + // remove the smallest num from sum + subSum += nums1[i]; + + // remove the smallest num from priority queue + pq.push(-nums1[i]); + + if(subSum * nums2[i] > maxProduct) + maxProduct = subSum * nums2[i]; + + subSum += pq.top(); + + pq.pop(); + } + return maxProduct; + } +}; \ No newline at end of file diff --git a/05- May/25- New 21 Game/25- New 21 Game (Ahmed Hossam).cpp b/05- May/25- New 21 Game/25- New 21 Game (Ahmed Hossam).cpp new file mode 100644 index 000000000..f49cd49aa --- /dev/null +++ b/05- May/25- New 21 Game/25- New 21 Game (Ahmed Hossam).cpp @@ -0,0 +1,36 @@ +// Author: Ahmed Hossam + +class Solution { +public: + double new21Game(int n, int k, int maxPts) { + if (k == 0 || n >= k + maxPts) return 1.0; + + // Create a vector to store the probabilities. + vector < double > dp(n + 1); + + // Initialize the current sum and the answer variables. + double currSum = 1.0, ans = 0.0; + + // Set the initial probability for getting 0 points to 1.0. + dp[0] = 1.0; + + // Calculate the probabilities for getting different points. + for (int i = 1; i <= n; i++) { + // Calculate the probability of getting i points. + dp[i] = currSum / maxPts; + + // Update the current sum or the answer based on the value of i. + // If i is less than k, update the current sum. + // Otherwise, update the answer. + (i < k ? currSum : ans) += dp[i]; + + // If i - maxPts is greater than or equal to 0, + // subtract the probability of getting (i - maxPts) points from the current sum. + if (i - maxPts >= 0) + currSum -= dp[i - maxPts]; + } + + // Return the final answer. + return ans; + } +}; diff --git a/05- May/25- New 21 Game/25- New 21 Game (Mina Magdy).cpp b/05- May/25- New 21 Game/25- New 21 Game (Mina Magdy).cpp new file mode 100644 index 000000000..f222d2352 --- /dev/null +++ b/05- May/25- New 21 Game/25- New 21 Game (Mina Magdy).cpp @@ -0,0 +1,33 @@ +// Author: Mina Magdy + +class Solution { +public: + // Function to calculate the winning probability in the New 21 Game + double new21Game(int n, int k, int maxPts, int curr = 0) { + // Base case: If k is 0, the game is already over, and the probability of winning is 1. + if (k == 0) return 1; + + double dp[n + 1]; // Array to store the probabilities + memset(dp, -1, sizeof(dp)); // Initialize the array with -1 + + double sum = 0; // Variable to store the sum of probabilities + int r = 0; // Variable to store the right endpoint of the interval + + // Fill the probabilities for the rightmost interval [k, min(n, (k-1)+maxPts)] + for (int i = k; i <= min(n, (k - 1) + maxPts); i++) { + dp[i] = 1; // Set the winning probability to 1 for these values + sum += dp[i]; // Update the sum + r = i; // Update the right endpoint + } + + // Calculate the probabilities for the remaining values in reverse order + for (int i = k - 1; i >= 0; i--) { + dp[i] = sum / maxPts; // Calculate the average of the next maxPts values + if (r - i + 1 > maxPts) + sum -= dp[r--]; // If the window size exceeds maxPts, remove the leftmost probability + sum += dp[i]; // Add the current probability to the sum + } + + return dp[0]; // Return the winning probability for starting with 0 points + } +}; diff --git a/05- May/26- Stone Game II/26- Stone Game II (Ahmed Hossam).cpp b/05- May/26- Stone Game II/26- Stone Game II (Ahmed Hossam).cpp new file mode 100644 index 000000000..984b851ea --- /dev/null +++ b/05- May/26- Stone Game II/26- Stone Game II (Ahmed Hossam).cpp @@ -0,0 +1,41 @@ +// Author: Ahmed Hossam + +class Solution { +public: + int stoneGameII(vector& piles) { + int n = piles.size(); + + // dp[i][m] represents the maximum number of stones the player can obtain + // when starting at pile i with a maximum pick of m. + vector < vector < int > > dp(n, vector < int > (2 * n + 5)); + + // sum[i] stores the sum of stones from pile i to the end. + vector < int > sum(n + 5); + + // Calculate the sum of stones from each pile to the end. + for (int i = n - 1; i >= 0; i--) + sum[i] = piles[i] + sum[i + 1]; + + // Iterate over the piles from right to left. + for (int i = n - 1; i >= 0; i--) { + // Iterate over the maximum pick from 1 to n. + for (int m = 1; m <= n; m++) { + if (i + 2 * m >= n) + // If there are not enough piles remaining, take all the stones. + dp[i][m] = sum[i]; + else { + // Consider all possible picks from 1 to 2 * m. + for (int x = 1; x <= 2 * m; x++) + // Calculate the maximum stones the player can obtain + // by either taking x stones and recursively solving for the remaining piles, + // or not taking any stones and letting the other player play. + dp[i][m] = max(dp[i][m], sum[i] - dp[i + x][max(m, x)]); + } + } + } + + // The maximum number of stones the first player can obtain starting from the first pile + // with a maximum pick of 1 is stored in dp[0][1]. + return dp[0][1]; + } +}; diff --git a/05- May/26- Stone Game II/26- Stone Game II (Emad Mohamed).cpp b/05- May/26- Stone Game II/26- Stone Game II (Emad Mohamed).cpp new file mode 100644 index 000000000..e55786ce0 --- /dev/null +++ b/05- May/26- Stone Game II/26- Stone Game II (Emad Mohamed).cpp @@ -0,0 +1,42 @@ +// Author: Emad Mohamed + /* +0 -> Alice’s turn +1 -> Bob’s turn +We will use dp to try all the possible solutions. +We are calculating dp relative to Alice only so +If turn is 0 (Alice’s turn) then dp refers to the highest score Alice can get. +If turn is 1 (Bob’s turn) then dp refers to the lowest score Alice can get from that position. +So Alice will try to maximize the result because that is her score +while Bob will try to find the minimum result because it’s Alice’s score. +Thus we will only add the sum in Alice’s turn. +*/ +class Solution { + int dp[100][1001][2], n; + int findBest(int idx, int m, bool turn, vector&piles){ + if(idx == n) + return 0; + int& ret = dp[idx][m][turn]; + if(~ret) return ret; + if(!turn){ + //Alice will try to maxmimize + ret = INT_MIN; + int sum = 0; + for(int x = 1; x <= 2 * m && idx + x <= n; x++){ + sum += piles[idx + x - 1]; + ret = max(ret, sum + findBest(idx + x, max(m, x), !turn, piles)); + } + }else{ + //Bob will try to minimize + ret = INT_MAX; + for(int x = 1; x <= 2 * m && idx + x <= n; x++) + ret = min(ret, findBest(idx + x, max(m, x), !turn, piles)); + } + return ret; + } +public: + int stoneGameII(vector& piles) { + memset(dp, -1, sizeof(dp)); + n = piles.size(); + return findBest(0, 1, 0, piles); + } +}; diff --git a/05- May/26- Stone Game II/26- Stone Game II (Mina Magdy).cpp b/05- May/26- Stone Game II/26- Stone Game II (Mina Magdy).cpp new file mode 100644 index 000000000..bc104a656 --- /dev/null +++ b/05- May/26- Stone Game II/26- Stone Game II (Mina Magdy).cpp @@ -0,0 +1,47 @@ +// Author: Mina Magdy + +// Define a class Solution +class Solution { +public: + vector>> dp; // Dynamic programming memoization table + + // Constructor to initialize the dp table + Solution() { + dp.assign(100, vector>(100, vector(2, -1))); + } + + // Recursive function to play the stone game + int rec(vector& piles, int idx = 0, int M = 1, int turn = 1) { + // Base case: if all piles have been visited, return 0 + if (idx >= piles.size()) + return 0; + + // Check if the current state has already been calculated + int &ret = dp[idx][M][turn]; + if (~ret) + return ret; + + // Turn 1: Alex's turn + if (turn) { + ret = 0; + int sum = 0; + for (int X = 1; idx + X - 1 < piles.size() && X <= 2 * M; X++) { + sum += piles[idx + X - 1]; + ret = max(ret, sum + rec(piles, idx + X, max(M, X), !turn)); + } + } + // Turn 0: Lee's turn + else { + ret = 1e9; + for (int X = 1; idx + X - 1 < piles.size() && X <= 2 * M; X++) { + ret = min(ret, rec(piles, idx + X, max(M, X), !turn)); + } + } + return ret; + } + + // Function to calculate the maximum number of stones Alex can get + int stoneGameII(vector& piles) { + return rec(piles); + } +}; diff --git a/05- May/27- Stone Game III/27- Stone Game III (Omar Sanad).cpp b/05- May/27- Stone Game III/27- Stone Game III (Omar Sanad).cpp new file mode 100644 index 000000000..7a1ee8a0c --- /dev/null +++ b/05- May/27- Stone Game III/27- Stone Game III (Omar Sanad).cpp @@ -0,0 +1,97 @@ +// author : Omar Sanad + +/*IMPORTANT: Below you will find another solution using dp iterative with rolling back */ + +/* We can solve this problem using dynamic programming +we will try for each player to take 1, 2, or 3 stones, +To mark who will win, we can take the sum of Alice's stones as positive, and sum of Bob's stones as negative, +In Alice's turn she will try to maximize the result, as if the final result is positive she wins +In Bob's turn he will try to minimize the resutl, as if the final result is negative he wins +If the final result is zero, it's a tie + */ +class Solution { +public: + // declaring a dp table for memoization + // declaring n (the size of the stones array) + int dp[50005][2], n; + + // declare the stones array inside the class itself, to use it anywhere inside the class + vector stoneValue; + + // the recursion function + int rec(int idx, bool Alice_turn) { + // if we have no stones, we end the game + if (idx >= n) + return 0; + + // initializing a variable ret to store the dp of the current state by reference to it, for ease use + int &ret = dp[idx][Alice_turn]; + + // if we have already calculated this state, then no need to calc it again, we just return its stored value + if (~ret) return ret; + + // else we initialize the ret with either one of the two values + // If this is Alice's turn, we initialize it to INT_MIN, as Alice wants to maximize + // else if this Bob's turn, we initialize it to INT_MAX, as Bob wants to minimize + ret = Alice_turn ? INT_MIN : INT_MAX; + + // declare a variable to store the curren sum which we will store the sum of 1st element, then 1st and 2nd, then 1st,2nd, and 3rd stones + int curSum = 0; + + // if this is Alice's turn, we would like to maximize the answer, and we will add the sum as positive + if (Alice_turn) { // I need to maximize + for (int i = 0; i < 3 && i + idx < n; i++) { + curSum += stoneValue[idx + i]; + ret = max(ret, curSum + rec(i + idx + 1, !Alice_turn)); + } + } + // else if it's Bob's turn, we would like to minimize the answer, and we will add the sum as negative + else{ // I need to minimize + for (int i = 0; i < 3 && i + idx < n; i++) { + curSum -= stoneValue[idx + i]; + ret = min(ret, curSum + rec(i + idx + 1, !Alice_turn)); + } + } + + // return the answer of this state + return ret; + } + + string stoneGameIII(vector& stoneValue) { + // fill the dp table with -1, mark as not yet calculated + memset(dp, -1, sizeof(dp)); + + // assign the given stoneValue to the stoneValue which is declared inside the class itself + this->stoneValue = stoneValue; + + // assign the size of the given array to n + n = stoneValue.size(); + + // return the answer to the problem + // if the answer is "positive" -> "Alice" + // if "negative" -> "Bob" + // if "ZERO" -> "Tie" + return rec(0, true) > 0 ? "Alice" : rec(0, true) < 0 ? "Bob" : "Tie"; + } +}; + + +//================================================================================================================================================================================================================ +//================================================================================================================================================================================================================ +//================================================================================================================================================================================================================ +// the dp iterative solution +class Solution { +public: + string stoneGameIII(vector& sv) { + int dp[4][2]{}, n = sv.size(); + for (int i = 0; i < 3; i++) + sv.push_back(0); + + for (int idx = n - 1; idx >= 0; idx--) { + dp[idx % 4][0] = min({-sv[idx] + dp[(idx + 1) % 4][1], -sv[idx] - sv[idx + 1] + dp[(idx + 2) % 4][1], -sv[idx] - sv[idx + 1] - sv[idx + 2] + dp[(idx + 3) % 4][1]}); + dp[idx % 4][1] = max({sv[idx] + dp[(idx + 1) % 4][0], sv[idx] + sv[idx + 1] + dp[(idx + 2) % 4][0], sv[idx] + sv[idx + 1] + sv[idx + 2] + dp[(idx + 3) % 4][0]}); + } + + return dp[0][true] > 0 ? "Alice" : dp[0][true] < 0 ? "Bob" : "Tie"; + } +}; diff --git a/05- May/README.md b/05- May/README.md index 072bc7bb9..c3786bffb 100644 --- a/05- May/README.md +++ b/05- May/README.md @@ -43,6 +43,9 @@ 1. **[Evaluate Division](#20--evaluate-division)** 1. **[Shortest Bridge](#21--shortest-bridge)** 1. **[Kth Largest Element in a Stream](#23--kth-largest-element-in-a-stream)** +1. **[Maximum Subsequence Score](#24--maximum-subsequence-score)** +1. **[New 21 Game](#25--new-21-game)** +1. **[Stone Game II](#26--stone-game-ii)**


@@ -1239,4 +1242,198 @@ public: } }; ``` + +
+

+ +## 24) [Maximum Subsequence Score](https://leetcode.com/problems/maximum-subsequence-score/) + +### Difficulty + +![](https://img.shields.io/badge/Medium-orange?style=for-the-badge) + +### Related Topic + +`Array` `Greedy` `Sorting` `Heap (Priority Queue)` + +### Code + + +```cpp +class Solution { +public: + long long maxScore(vector& nums1, vector& nums2, int k) { + // Get the size of nums1 + int n = nums1.size(); + + // Create a vector of indices from 0 to n - 1 + vector < int > idx(n); + iota(idx.begin(), idx.end(), 0); + + // Sort the indices based on the corresponding values in nums2 + sort(idx.begin(), idx.end(), [&](int i, int j){ + return nums2[i] < nums2[j]; + }); + + // Create a min-heap priority queue + priority_queue < int, vector < int >, greater < int > > pq; + + // Variables to keep track of the current sum and maximum sequence + long long curr_sum = 0, max_seq = 0; + + // Lambda function to add an element to the current sum and the priority queue + auto add = [&](int x){ + curr_sum += x; + pq.push(x); + }; + + // Lambda function to remove the smallest element from the current sum and the priority queue + auto remove = [&](){ + curr_sum -= pq.top(); + pq.pop(); + }; + + // Iterate over the indices in reverse order + for(int i = n - 1; i >= 0; i--){ + // Add the corresponding element from nums1 to the current sum and the priority queue + add(nums1[idx[i]]); + + // If the size of the priority queue reaches k, update the maximum sequence and remove the smallest element + if(pq.size() == k){ + max_seq = max(max_seq, curr_sum * nums2[idx[i]]); + remove(); + } + } + + // Return the maximum sequence + return max_seq; + } +}; +``` + +
+

+ +## 25) [New 21 Game](https://leetcode.com/problems/new-21-game/) + +### Difficulty + +![](https://img.shields.io/badge/Medium-orange?style=for-the-badge) + +### Related Topic + +`Math` `Dynamic Programming` `Sliding Window` `Probability and Statistics` + +### Code + + +```cpp +class Solution { +public: + long long maxScore(vector& nums1, vector& nums2, int k) { + // Get the size of nums1 + int n = nums1.size(); + + // Create a vector of indices from 0 to n - 1 + vector < int > idx(n); + iota(idx.begin(), idx.end(), 0); + + // Sort the indices based on the corresponding values in nums2 + sort(idx.begin(), idx.end(), [&](int i, int j){ + return nums2[i] < nums2[j]; + }); + + // Create a min-heap priority queue + priority_queue < int, vector < int >, greater < int > > pq; + + // Variables to keep track of the current sum and maximum sequence + long long curr_sum = 0, max_seq = 0; + + // Lambda function to add an element to the current sum and the priority queue + auto add = [&](int x){ + curr_sum += x; + pq.push(x); + }; + + // Lambda function to remove the smallest element from the current sum and the priority queue + auto remove = [&](){ + curr_sum -= pq.top(); + pq.pop(); + }; + + // Iterate over the indices in reverse order + for(int i = n - 1; i >= 0; i--){ + // Add the corresponding element from nums1 to the current sum and the priority queue + add(nums1[idx[i]]); + + // If the size of the priority queue reaches k, update the maximum sequence and remove the smallest element + if(pq.size() == k){ + max_seq = max(max_seq, curr_sum * nums2[idx[i]]); + remove(); + } + } + + // Return the maximum sequence + return max_seq; + } +}; +``` + +
+

+ +## 26) [Stone Game II](https://leetcode.com/problems/stone-game-ii/) + +### Difficulty + +![](https://img.shields.io/badge/Medium-orange?style=for-the-badge) + +### Related Topic + +`Array` `Math` `Dynamic Programming` `Game Theory` + +### Code + + +```cpp +class Solution { +public: + int stoneGameII(vector& piles) { + int n = piles.size(); + + // dp[i][m] represents the maximum number of stones the player can obtain + // when starting at pile i with a maximum pick of m. + vector < vector < int > > dp(n, vector < int > (2 * n + 5)); + + // sum[i] stores the sum of stones from pile i to the end. + vector < int > sum(n + 5); + + // Calculate the sum of stones from each pile to the end. + for (int i = n - 1; i >= 0; i--) + sum[i] = piles[i] + sum[i + 1]; + + // Iterate over the piles from right to left. + for (int i = n - 1; i >= 0; i--) { + // Iterate over the maximum pick from 1 to n. + for (int m = 1; m <= n; m++) { + if (i + 2 * m >= n) + // If there are not enough piles remaining, take all the stones. + dp[i][m] = sum[i]; + else { + // Consider all possible picks from 1 to 2 * m. + for (int x = 1; x <= 2 * m; x++) + // Calculate the maximum stones the player can obtain + // by either taking x stones and recursively solving for the remaining piles, + // or not taking any stones and letting the other player play. + dp[i][m] = max(dp[i][m], sum[i] - dp[i + x][max(m, x)]); + } + } + } + + // The maximum number of stones the first player can obtain starting from the first pile + // with a maximum pick of 1 is stored in dp[0][1]. + return dp[0][1]; + } +}; +``` \ No newline at end of file