Skip to content

Commit

Permalink
Merge branch '7oSkaaa:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
AhmedGamal2212 committed May 15, 2023
2 parents b741811 + 05ffad8 commit 041e726
Show file tree
Hide file tree
Showing 6 changed files with 340 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Author: Mahmoud Aboelsoud

class Solution {
public:
// we need to count the number of ways to build a string of length between low and high
// we will use dp to count the number of ways to build a string of length n
// we will use a recursive function to count the number of ways to build a string of length n
// the recursive function will return 0 if n > high


// dp: dp[i] -> number of ways to build a string of length i
// low: the minimum length of the string
// high: the maximum length of the string
// zero: the number of zeros you can append to the string
// one: the number of ones you can append to the string
int dp[100005], low, high, zero, one, mod = 1e9 + 7;

// recursive function to count the number of ways to build a string of length n
int cnt_ways(int n){
// if n > high return 0
if(n > high) return 0;

// if n is calculated before return the value
if(dp[n] != -1) return dp[n];

// if n is in the range [low, high] then add 1 to the answer
int ans = (n >= low);

// add the number of ways to build a string of length n + zero
ans += cnt_ways(n + zero);
ans %= mod;
// add the number of ways to build a string of length n + one
ans += cnt_ways(n + one);
ans %= mod;

// return the answer
return dp[n] = ans;
}

int countGoodStrings(int low, int high, int zero, int one){
// initialize dp with -1
memset(dp, -1, sizeof(dp));
// initialize the global variables
this -> low = low, this -> high = high, this -> zero = zero, this -> one = one;

// return the number of ways to build a string of length between low and high starting from length 0
return cnt_ways(0);
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Author: Ahmed Hossam

class Solution {
public:

// declare variables
int n, full_mask;
// vectors to store numbers and dynamic programming results
vector<int> nums, dp;

// function to check if a bit is empty in a binary mask
bool is_empty_bit(int bit, int mask){
return !(mask & (1 << bit));
}

// recursive function to calculate the maximum score
int max_score(int mask){
// if all bits are filled, return 0
if(mask == full_mask) return 0;
// use memoization to avoid redundant computations
int& ret = dp[mask];
// calculate the current index based on the number of filled bits
int idx = __builtin_popcount(mask) / 2 + 1;
// if the result has already been calculated, return it
if(~ret) return ret;
ret = 0;
// iterate over all pairs of numbers
for(int i = 0; i < n; i++)
for(int j = i + 1; j < n; j++)
// if both numbers are empty, calculate the score
if(is_empty_bit(i, mask) && is_empty_bit(j, mask))
ret = max(ret, (idx * __gcd(nums[i], nums[j])) + max_score(mask | (1 << i) | (1 << j)));
// return the maximum score
return ret;
}

int maxScore(vector<int>& nums) {
// set the number of elements
n = nums.size();
// set the vector of numbers
this -> nums = nums;
// set the full binary mask
full_mask = (1 << n) - 1;
// initialize the dynamic programming vector with -1
dp = vector<int>(1 << n, -1);
// return the maximum score starting with an empty mask
return max_score(0);
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Author: Lama Salah

class Solution {
public:
// Declare the size of the list and memoization array.
int n, memo[8][100000];

int dp(int i, int mask, vector <int>& nums){
// If we've performed all operations, return 0 - (the base-case).
if (i > n) return 0;

// Get a reference to the memoized result for this i and mask and check if the result is already memoized.
int& ans = memo[i][mask];
if (~ans) return ans;

// Loop over all possible unremoved pairs.
for (int k = 0; k < 2*n; k++){
// Check if the k-th bit in the mask is 0 (the k-th integer has not been removed).
if (!((mask >> k) & 1)){
// Set the k-th bit in the mask to 1 (remove the k-th integer).
mask |= (1 << k);

// Loop over all possible unremoved integers.
for (int l = 0; l < 2*n; l++){
// check If the l-th bit in the mask is 0 (the l-th integer has not been removed).
if (!((mask >> l) & 1)){

// Set the l-th bit in the mask to 1 (remove the l-th integer).
mask |= (1 << l);

// Compute the score for using the k-th and l-th integers.
ans = max(ans, (i* gcd(nums[k], nums[l])) + dp(i+1, mask, nums));

// Unset the l-th bit in the mask.
mask ^= (1 << l);
}
}

// Unset the k-th bit in the mask.
mask ^= (1 << k);
}
}

return ans;
}

int maxScore(vector<int>& nums) {
this -> n = nums.size()/2;

// Initialize the memo array with -1 values using the memset() function.
memset(memo, -1, sizeof memo);

// Compute the maximum score after N operations.
return dp(1, 0, nums);
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@

// Author: MohamedEmara

class Solution {
public:

int n;
int dp[20][20000];
int arr[20];

int rec(int idx, int mask)
{
// the base case WHEN all bits are set to one
if(mask == (1<<(2*n))-1)
return 0;

int &ret = dp[idx][mask];
if(~ret)
return ret;


ret = 0;

for(int i=0; i<2*n; i++)
{
for(int j=i+1; j<2*n; j++)
{
// if the two bits i , j not taken yet in the mask
// try to take them and maximize the value.
if(!(mask & (1 << j)) && !(mask & (1 << i)))
{
// set two bits of one ie: add the value of these two bits
int tmp = mask + (1 << j) + (1 << i);
ret = fmax(ret, idx * __gcd(arr[i], arr[j]) + rec(idx+1, tmp));
}
}
}

return ret;
}


int maxScore(vector<int>& nums) {
ios_base::sync_with_stdio(false);
cin.tie(NULL);


n = nums.size() / 2;

// At every idx(ith operation)
// We will try to choose two distinct numbers
// An save the taken elements in a mask that is intially all zeros
// the two taken element --> set their bits to one and continue trying other elements
// till the mask becoms all ones of lenght 2*N --> (1 << (2*n) - 1)

memset(dp, -1, sizeof(dp));
for(int i=0; i<2*n; i++)
arr[i] = nums[i];

return rec(1, 0);
}
};


Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// author : Omar Sanad

class Solution {
public:
// declare the array nums in the class itslef, to use it anywhere in the class
vector < int > nums;

// declare a 2D array for the memoization
// declare the number of steps (n)
// declare the size of the array which equals 2 * n
int dp[15][1 << 14], n, the_sz;
int rec(int idx, int mask) {

// if we've already done the n operations, then we return
if (idx > n)
return 0;

// assign the dp[idx][mask] to ret by reference to use it easily
int &ret = dp[idx][mask];

// if this state was already been calculated, then we return its answer
if (~ret) return ret;

// otherwise we initialize the answer with 0
ret = 0;

// we iterate over the elements of the array, and for every two unvisited elements we try taking them for this step
for (int i = 0; i < the_sz; i++)
if ((mask & (1 << i)) == 0)
for (int j = i + 1; j < the_sz; j++)
if ((mask & (1 << j)) == 0)
// if we try to take nums[i], nums[j]
// then we mark them as visited in the mask --> mask | (1 << j) | (1 << i)
ret = max(ret, idx * gcd(nums[i], nums[j]) + rec(idx + 1, mask | (1 << j) | (1 << i)));


// return the answer for this state
return ret;
}
int maxScore(vector<int>& nums) {

// assign the passed array nums to the array nums which is declared inside the class itself
this->nums = nums;

this->the_sz = nums.size(); // the size of the array
this->n = the_sz / 2; // the number of operations to be done

// initialize the array dp with -1, in other words mark as not calculated
memset(dp, -1, sizeof(dp));


// return the answer to the problem
return rec(1, 0);
}
};
67 changes: 67 additions & 0 deletions 05- May/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
1. **[Uncrossed Lines](#11--uncrossed-lines)**
1. **[Solving Questions With Brainpower](#12--solving-questions-with-brainpower)**
1. **[Count Ways To Build Good Strings](#13--count-ways-to-build-good-strings)**
1. **[Maximize Score After N Operations](#14--maximize-score-after-n-operations)**

<hr>
<br><br>
Expand Down Expand Up @@ -727,4 +728,70 @@ public:
}
};
```
<hr>
<br><br>
## 14) [Maximize Score After N Operations](https://leetcode.com/problems/maximize-score-after-n-operations/)
### Difficulty
![](https://img.shields.io/badge/Hard-red?style=for-the-badge)
### Related Topic
`Array` `Math` `Dynamic Programming` `Backtracking` `Bit Manipulation` `Number Theory` `Bitmask`
### Code
```cpp
class Solution {
public:
// declare variables
int n, full_mask;
// vectors to store numbers and dynamic programming results
vector<int> nums, dp;
// function to check if a bit is empty in a binary mask
bool is_empty_bit(int bit, int mask){
return !(mask & (1 << bit));
}
// recursive function to calculate the maximum score
int max_score(int mask){
// if all bits are filled, return 0
if(mask == full_mask) return 0;
// use memoization to avoid redundant computations
int& ret = dp[mask];
// calculate the current index based on the number of filled bits
int idx = __builtin_popcount(mask) / 2 + 1;
// if the result has already been calculated, return it
if(~ret) return ret;
ret = 0;
// iterate over all pairs of numbers
for(int i = 0; i < n; i++)
for(int j = i + 1; j < n; j++)
// if both numbers are empty, calculate the score
if(is_empty_bit(i, mask) && is_empty_bit(j, mask))
ret = max(ret, (idx * __gcd(nums[i], nums[j])) + max_score(mask | (1 << i) | (1 << j)));
// return the maximum score
return ret;
}
int maxScore(vector<int>& nums) {
// set the number of elements
n = nums.size();
// set the vector of numbers
this -> nums = nums;
// set the full binary mask
full_mask = (1 << n) - 1;
// initialize the dynamic programming vector with -1
dp = vector<int>(1 << n, -1);
// return the maximum score starting with an empty mask
return max_score(0);
}
};
```

0 comments on commit 041e726

Please sign in to comment.