├── Codechef ├── ALTARRAY.cpp ├── DBOY.cpp ├── DELISH.cpp ├── GRID.cpp ├── TREES.cpp └── XORSUB.cpp ├── Codeforces ├── 1114D.cpp ├── 1132F.cpp ├── 118D.cpp ├── 2B.cpp ├── 414B.cpp ├── 431C.cpp ├── 455A.cpp ├── 467C.cpp └── 474D.cpp ├── Coding Ninjas ├── Flags.cpp └── ShortestSubsequence.cpp ├── Geeks For Geeks ├── Cutted Segments.cpp ├── Distinct Subsequences Sum In An Array.cpp ├── Elements With Left Side Smaller And Right Side Greater.cpp ├── Form A Palindrome.cpp ├── Maximum Product Subarray.cpp ├── Maximum Sum Without Adjacents.cpp ├── Number of ways of scoring R runs in B balls with at most W wickets.cpp └── Number of ways to partition a string into two balanced subsequences.cpp ├── Hackerrank ├── Construct The Array.cpp ├── Sherlock And Costs.cpp └── Stock Maximize.cpp ├── InterviewBit ├── ArrangeII.cpp ├── BestTimeToBuyAndSellStocksI.cpp ├── BestTimeToBuyAndSellStocksII.cpp ├── BestTimeToBuyAndSellStocksIII.cpp ├── BestTimeToBuyAndSellStocksIIIOptimized.cpp ├── CoinSumInfinite.cpp ├── CoinsInALine.cpp ├── CountPermuatationsOfBST.cpp ├── DecodeString.cpp ├── DistinctSubsequences.cpp ├── DungeonPrincess.cpp ├── EditDistance.cpp ├── EqualAveragePartition.cpp ├── EvaluateExpressionToTrue.cpp ├── FlipArray.cpp ├── InterleavingStrings.cpp ├── Intersecting Chords In A Circle.cpp ├── Jesse And Two Strings.cpp ├── JumpGameArray.cpp ├── Kingdom War.cpp ├── KthManhattanDistanceNeigbhourhood.cpp ├── Largest Area Of Rectangle With Permutations.cpp ├── LastStoneWeightII.cpp ├── Length Of Longest Subsequence.cpp ├── Let'sParty.cpp ├── Longest Arithmetic Progression.cpp ├── Longest Valid Parentheses.cpp ├── LongestValidParentheses.cpp ├── Max Rectangle In Binary Matrix.cpp ├── MaxSumWithoutAdjacentElements.cpp ├── MaximumSum.cpp ├── MinJumpsArray.cpp ├── MinJumpsArray_Optimized.cpp ├── MinSumPathInMatrix.cpp ├── MinSumPathInTriangle.cpp ├── NDigitNumbersWithDigitSumS.cpp ├── OddPalindrome.cpp ├── PalindromePartitioning.cpp ├── Queen Attack.cpp ├── RegularExpressionII.cpp ├── RegularExpressionMatch.cpp ├── Remove The Substring.cpp ├── RemoveTrees.cpp ├── RepeatingSubSequence.cpp ├── RodCutting.cpp ├── ScrambleString.cpp ├── SmallestSequenceWithGivenPrimes.cpp ├── Submatrices WIth Sum Zero.cpp ├── Tushar's Birthday Bombs.cpp ├── Tushar'sBirthdayParty.cpp ├── TwoStrings.cpp ├── UniquePathsInAGrid.cpp ├── Ways To Color A 3XN Board.cpp ├── Ways To Decode.cpp └── WordBreak.cpp ├── LeetCode ├── 1-bit And 2-bit Characters.cpp ├── 120_recursion.cpp ├── 120_space_optimized.cpp ├── 139.cpp ├── 2 Keys Keyboard.cpp ├── 2369.cpp ├── 322.cpp ├── 329.cpp ├── 91.cpp ├── Airplane Seat Assignment Probability.cpp ├── Arithmetic Slices II.cpp ├── Array Nesting.cpp ├── Beautiful Arrangement.cpp ├── Best Time To Buy And Sell Stock With Transaction Fee.cpp ├── BestTimeToBuyAndSellStockIII.cpp ├── BestTimeToBuyAndSellStockIV.cpp ├── Binary Trees With Factors.cpp ├── Bitmasking │ └── SmallestSufficientTeam.cpp ├── Build Array Where You Can Find The Maximum Exactly K Comparisons.cpp ├── BurstBallons.cpp ├── Can I Win.cpp ├── Champagne Tower.cpp ├── Cherry Pickup.cpp ├── Concatenated Words.cpp ├── CorporateFlightBookings.cpp ├── Count Square Submatrices With All Ones.cpp ├── Count Vowels Permutation.cpp ├── Decode Ways.cpp ├── Delete And Earn.cpp ├── Delete Columns To Make Sorted III.cpp ├── Delete Operation For Two Strings.cpp ├── Dice Roll Simulation.cpp ├── Different Ways To Add Parentheses.cpp ├── Distinct Subsequences II.cpp ├── DistinctSubsequencesII.cpp ├── DivisorGame.cpp ├── Filling Bookcase Shelves.cpp ├── Find The Shortest Superstring.cpp ├── Flip String To Monotone Increasing.cpp ├── Guess Number Higher Or Lower II Iterative.cpp ├── Guess Number Higher Or Lower II.cpp ├── Jump Game V.cpp ├── K Inverse Pairs Array.cpp ├── K-Similar Strings.cpp ├── KnightDialer.cpp ├── Largest 1 Bordered Square.cpp ├── Largest Divisible Subset.cpp ├── Largest Plus Sign.cpp ├── LargestSumOfAverages.cpp ├── LastStoneWeightII.cpp ├── Length Of Longest Fibonacci Sequence.cpp ├── Longest Arithmetic Sequence Of Given Difference.cpp ├── Longest Increasing Path In A Matrix.cpp ├── Longest Turbulent Subarray.cpp ├── LongestArithmeticSequenceLength.cpp ├── LongestValidParentheses.cpp ├── Loud And Rich.cpp ├── Make Array Strictly Increasing.cpp ├── Max Subarray Sum With One Deletion.cpp ├── MaxProductSubarray.cpp ├── Maximum Length Of A Concatenated String With Unique Characters.cpp ├── Maximum Profit In Job Scheduling.cpp ├── Maximum Score Word Formed By Letters.cpp ├── MaximumSumNonConsecutive.cpp ├── Minimum ASCII Delete Sum For Two Strings(Rev).cpp ├── Minimum ASCII Delete Sum For Two Strings.cpp ├── Minimum Cost Tree From Leaves.cpp ├── Minimum Difficulty Of A Job Schedule.cpp ├── Minimum Distance To Type A Word Using Two Fingers.cpp ├── Minimum Falling Path Sum II.cpp ├── Minimum Insertion Steps To Make A String Palindrome.cpp ├── Minimum Number Of Taps To Open To Water A Garden.cpp ├── Minimum Score Triangulation Of Polygon.cpp ├── Minimum Swap To Make Sequences Increasing.cpp ├── MinimumCostForTickets.cpp ├── Number Of Longest Increasing Subsequence.cpp ├── Number Of Music Playlists.cpp ├── Number Of Paths With Max Score.cpp ├── Number Of Ways To Stay In Same Place After Some Steps.cpp ├── NumbersWithSameConsecutiveDifferences.cpp ├── Odd Even Jump(Iterative).cpp ├── Odd Even Jump.cpp ├── Ones And Zeroes.cpp ├── Out Of Boundary Paths.cpp ├── Palindrome Partitioning III.cpp ├── ParsingABooleanExpression.cpp ├── Partition Array For Maximum Sum.cpp ├── PartitionToKEqualSumSubsets.cpp ├── ProductOfArrayExceptSelf.cpp ├── Profitable Schemes.cpp ├── Reducing Dishes.cpp ├── Russian Doll Envelope.cpp ├── Shortest Path Of A Grid With Obstacles Elimination.cpp ├── Soup Servings.cpp ├── Stone Game II.cpp ├── Stone Game III.cpp ├── Stone Game.cpp ├── Strange Printer.cpp ├── Student Attendance Record II.cpp ├── Super Egg Drop.cpp ├── Swap For Longest Repeated Character Substring.cpp ├── Tallest Billboard.cpp ├── Target Sum.cpp ├── Tiling A Rectangle With The Fewest Squares.cpp ├── Toss Strange Coins.cpp ├── Uncrossed Lines.cpp ├── Valid Palindrome II.cpp ├── Valid Palindrome.cpp └── Valid Permutations Of DI Sequence.cpp ├── Longest Repeated Character Substring.cpp ├── Maximum Length Of Repeated Subarray.cpp ├── Maximum Sum Of Three Non Overlapping Subarrays.cpp └── README.md /Codechef/ALTARRAY.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int main() { 5 | int t; 6 | cin >> t; 7 | while(t--) { 8 | int n; 9 | cin >> n; 10 | vector a(n), dp(n, 1); 11 | for(int i = 0; i < n; i++) { 12 | cin >> a[i]; 13 | } 14 | for(int i = n - 2; i >= 0; i--) { 15 | if((a[i] > 0) ^ (a[i + 1] > 0) == 1) { 16 | dp[i] = dp[i + 1] + 1; 17 | } 18 | else 19 | dp[i] = 1; 20 | } 21 | for(int i = 0; i < n; i++) 22 | cout << dp[i] << " "; 23 | cout << endl; 24 | } 25 | return 0; 26 | } 27 | 28 | -------------------------------------------------------------------------------- /Codechef/DBOY.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int main() { 5 | int t; 6 | cin >> t; 7 | while(t--) { 8 | int n; 9 | cin >> n; 10 | vector h(n), k(n); 11 | for(int i = 0; i < n; i++) 12 | cin >> h[i]; 13 | for(int i = 0; i < n; i++) 14 | cin >> k[i]; 15 | int mx = *max_element(h.begin(), h.end()); 16 | vector dp(2 * mx + 1, 1e5); 17 | dp[0] = 0; 18 | for(int i = 0; i < n; i++) { 19 | for(int j = k[i]; j <= 2 * mx; j++) { 20 | dp[j] = min(dp[j], dp[j - k[i]] + 1); 21 | } 22 | } 23 | int ans = 0; 24 | for(int i = 0; i < n; i++) 25 | ans += dp[2 * h[i]]; 26 | cout << ans << endl; 27 | } 28 | return 0; 29 | } 30 | 31 | -------------------------------------------------------------------------------- /Codechef/DELISH.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #define ll long long int 5 | 6 | int main() { 7 | int t; 8 | cin >> t; 9 | while(t--) { 10 | int n; 11 | cin >> n; 12 | vector v(n), mxL(n, 0), mxR(n, 0), mnL(n, 0), 13 | mnR(n, 0); 14 | for(int i = 0; i < n; i++) { 15 | cin >> v[i]; 16 | } 17 | mxL[0] = mnL[0] = v[0]; 18 | for(int i = 1; i < n; i++) { 19 | mxL[i] = max(mxL[i - 1] + v[i], v[i]); 20 | mnL[i] = min(mnL[i - 1] + v[i], v[i]); 21 | } 22 | mxR[n - 1] = v[n - 1], mnR[n - 1] = v[n - 1]; 23 | for(int i = n - 2; i >= 0; i--) { 24 | mxR[i] = max(mxR[i + 1] + v[i], v[i]); 25 | mnR[i] = min(mnR[i + 1] + v[i], v[i]); 26 | } 27 | ll maxDiff = 0; 28 | for(int i = 0; i < n - 1; i++) { 29 | maxDiff = max(maxDiff, abs(mxL[i] - mnR[i + 1])); 30 | maxDiff = max(maxDiff, abs(mxR[i + 1] - mnL[i])); 31 | } 32 | cout << maxDiff << endl; 33 | } 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /Codechef/GRID.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int main() { 5 | int t; 6 | cin >> t; 7 | while(t--) { 8 | int n; 9 | cin >> n; 10 | char a[n + 1][n + 1]; 11 | int rsum[n + 1][n + 1]; 12 | int csum[n + 1][n + 1]; 13 | memset(rsum, 0, sizeof rsum); 14 | memset(csum, 0, sizeof csum); 15 | for(int i = 0; i < n; i++) { 16 | for(int j = 0; j < n; j++) { 17 | cin >> a[i][j]; 18 | } 19 | } 20 | int cnt = 0; 21 | for(int i = n - 1; i >= 0; i--) { 22 | for(int j = n - 1; j >= 0; j--) { 23 | rsum[i][j] += (rsum[i][j + 1] + (a[i][j] == '#')); 24 | csum[i][j] += (csum[i + 1][j] + (a[i][j] == '#')); 25 | if(!rsum[i][j] && !csum[i][j]) 26 | cnt++; 27 | } 28 | } 29 | cout << cnt << endl; 30 | } 31 | return 0; 32 | } 33 | 34 | -------------------------------------------------------------------------------- /Codechef/TREES.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #define ll long long int 5 | 6 | vector adj[65]; 7 | ll way[65][65][2]; 8 | 9 | ll ways(ll root, ll k, bool selRoot) { 10 | vis[root] = true; 11 | if(way[root][k][selRoot] != -1) 12 | return way[root][k][selRoot]; 13 | ll ans = 0; 14 | if(selRoot) { 15 | k--; 16 | int sz = adj[root].size(); 17 | for(int i = 0; i < sz; i++) { 18 | int ch = adj[root][i]; 19 | if(!vis[ch]) { 20 | for(int j = 0; j <= k; j++) { 21 | ans += (ways(ch, j, 1) * dp[sz - 1][k - j]); 22 | } 23 | } 24 | } 25 | } 26 | 27 | else { 28 | int sz = adj[root].size(); 29 | for(int i = 0; i < sz; i++) { 30 | ans += ways(ch, k, 1); 31 | } 32 | } 33 | return way[root][ll][selRoot] = ans; 34 | } 35 | 36 | int finddp(int n, int k) { 37 | 38 | } 39 | 40 | int main() { 41 | int t; 42 | cin >> t; 43 | while(t--) { 44 | memset(vis, 0, sizeof vis); 45 | memset(dp, 0, sizeof dp); 46 | memset(way, -1, sizeof way); 47 | adj.clear(); 48 | int n, k; 49 | cin >> n >> k; 50 | dp[0][0] = 1; 51 | for(int i = 0; i < n; i++) 52 | dp[i][0] = 0; 53 | finddp(n, k); 54 | for(int i = 0; i < n - 1; i++) { 55 | int u, v; 56 | cin >> u >> v; 57 | adj[u].push_back(v); 58 | adj[v].push_back(u); 59 | } 60 | int ans = 0; 61 | for(int i = 0; i < n; i++) { 62 | for(int j = 0; j <= k; j++) { 63 | memset(vis, 0, sizeof vis); 64 | ans += (ways(i, j, 0) + ways(i, j, 1)); 65 | } 66 | } 67 | cout << ans << endl; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Codechef/XORSUB.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int main() { 5 | int t; 6 | cin >> t; 7 | while(t--) { 8 | int n, k; 9 | cin >> n >> k; 10 | int v[n]; 11 | bool dp[1025] = {0}; 12 | dp[0] = 1; 13 | for(int i = 0; i < n; i++) 14 | cin >> v[i]; 15 | for(int i = 0; i < n; i++) { 16 | for(int j = 0; j <= 1024; j++) { 17 | dp[j ^ v[i]] = dp[j] | dp[j ^ v[i]]; 18 | } 19 | } 20 | int mx = 0; 21 | for(int i = 0; i <= 1024; i++) { 22 | if(dp[i]) 23 | mx = max(mx, i ^ k); 24 | } 25 | cout << mx << endl; 26 | } 27 | return 0; 28 | } 29 | 30 | -------------------------------------------------------------------------------- /Codeforces/1114D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #define int long long int 5 | #define vi vector 6 | #define vvi vector 7 | #define read(a) for(int i = 0; i < n; i++) cin >> a[i]; 8 | #define print(a) for(int i = 0; i < n; i++) cout << a[i] << " "; 9 | #define pb push_back 10 | #define pql priority_queue 11 | #define pqs priority_queue> 12 | #define pqlv priority_queue 13 | #define pqsv priority_queue> 14 | #define endl '\n' 15 | #define N 300002 16 | 17 | signed main() { 18 | ios::sync_with_stdio(false); 19 | cin.tie(0); 20 | cout.tie(0); 21 | int t = 1; 22 | // cin >> t; 23 | while(t--) { 24 | int n; 25 | cin >> n; 26 | vi v; 27 | for(int i = 0; i < n; i++) { 28 | int x; 29 | cin >> x; 30 | if(v.empty() || x != v.back()) 31 | v.pb(x); 32 | } 33 | int dp[5001][5001]; 34 | for(int r = 0; r < v.size(); r++) { 35 | for(int l = r; l >= 0; l--) { 36 | dp[l][r] = 1e9; 37 | if(l == r) { 38 | dp[l][r] = 0; 39 | } 40 | else { 41 | dp[l][r] = min(dp[l + 1][r], dp[l][r - 1]) + 1; 42 | if(v[l] == v[r]) { 43 | dp[l][r] = min(dp[l][r], 1 + dp[l + 1][r - 1]); 44 | } 45 | } 46 | } 47 | } 48 | cout << dp[0][v.size() - 1] << endl; 49 | } 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /Codeforces/1132F.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int n; 5 | string s; 6 | int dp[501][501]; 7 | 8 | int minCost(int i, int j) { 9 | if(i > j) 10 | return 0; 11 | if(i == j) 12 | return 1; 13 | if(dp[i][j] != -1) 14 | return dp[i][j]; 15 | int res = minCost(i + 1, j) + 1; 16 | for(int k = i + 1; k <= j; k++) { 17 | if(s[i] == s[k]) { 18 | res = min(res, minCost(i + 1, k - 1) + minCost(k, j)); 19 | } 20 | } 21 | return dp[i][j] = res; 22 | } 23 | 24 | int main() { 25 | memset(dp, -1, sizeof dp); 26 | cin >> n >> s; 27 | cout << minCost(0, n - 1); 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /Codeforces/118D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #define ll long long int 5 | #define MAX1 1001 6 | #define MAX2 101 7 | 8 | ll n1, n2, k1, k2; 9 | 10 | ll dp[MAX1][MAX1][2]; 11 | 12 | int main() { 13 | const ll MOD = 1e8; 14 | memset(dp, 0, sizeof dp); 15 | cin >> n1 >> n2 >> k1 >> k2; 16 | dp[0][0][0] = dp[0][0][1] = 1; 17 | for(ll i = 0; i <= n1; i++) { 18 | for(ll j = 0; j <= n2; j++) { 19 | for(ll k = 1; k <= k1; k++) { 20 | if(i >= k) 21 | dp[i][j][0] = (dp[i][j][0] % MOD + dp[i - k][j][1] % MOD) % MOD; 22 | } 23 | for(ll k = 1; k <= k2; k++) { 24 | if(j >= k) 25 | dp[i][j][1] = (dp[i][j][1] % MOD + dp[i][j - k][0] % MOD) % MOD; 26 | } 27 | } 28 | } 29 | cout << (dp[n1][n2][0] + dp[n1][n2][1]) % MOD; 30 | return 0; 31 | } 32 | 33 | -------------------------------------------------------------------------------- /Codeforces/2B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | typedef long long ll; 4 | 5 | #define N 1005 6 | 7 | 8 | int n, a[N][N], dp2[N][N], dp5[N][N]; 9 | 10 | void walk(int dp[N][N], int i, int j) { 11 | if(i == 1 && j == 1) 12 | return; 13 | if(dp[i - 1][j] < dp[i][j - 1]) { 14 | walk(dp, i - 1, j); 15 | printf("D"); 16 | } 17 | else { 18 | walk(dp, i, j - 1); 19 | printf("R"); 20 | } 21 | } 22 | 23 | int main() { 24 | ios_base::sync_with_stdio(false); 25 | cin.tie(NULL); 26 | memset(dp2, 50, sizeof dp2); 27 | memset(dp5, 50, sizeof dp5); 28 | dp2[0][1] = dp5[0][1] = dp2[1][0] = dp5[1][0] = 0; 29 | cin >> n; 30 | for(int i = 1; i <= n; i++) { 31 | for(int j = 1; j <= n; j++) { 32 | cin >> a[i][j]; 33 | } 34 | } 35 | bool zero = false; 36 | int x, y; 37 | for(int i = 1; i <= n; i++) { 38 | for(int j = 1; j <= n; j++) { 39 | if(!a[i][j]) { 40 | zero = 1; 41 | x = i; y = j; 42 | continue; 43 | } 44 | int num = a[i][j], c2 = 0, c5 = 0; 45 | while(num % 2 == 0) { 46 | num /= 2; 47 | c2++; 48 | } 49 | while(num % 5 == 0) { 50 | num /= 5; 51 | c5++; 52 | } 53 | dp2[i][j] = c2 + min(dp2[i - 1][j], dp2[i][j - 1]); 54 | dp5[i][j] = c5 + min(dp5[i - 1][j], dp5[i][j - 1]); 55 | } 56 | } 57 | int lrnd = min(dp2[n][n], dp5[n][n]); 58 | if(zero) 59 | lrnd = min(lrnd, 1); 60 | printf("%d\n", lrnd); 61 | if(lrnd == dp2[n][n]) 62 | walk(dp2, n, n); 63 | else if(lrnd == dp5[n][n]) 64 | walk(dp5, n, n); 65 | else { 66 | int i = 1, j = 1; 67 | while(i < x) 68 | printf("D"), ++i; 69 | while(j < y) 70 | printf("R"), ++j; 71 | while(i < n) 72 | printf("D"), ++i; 73 | while(j < n) 74 | printf("R"), ++j; 75 | } 76 | } 77 | 78 | -------------------------------------------------------------------------------- /Codeforces/414B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #define ll long long int 5 | #define MOD 1000000007 6 | #define MAX 2002 7 | 8 | ll n, k; 9 | 10 | ll dp[MAX][MAX]; 11 | 12 | ll f(ll num, ll k) { 13 | if(k == 0) 14 | return 1; 15 | if(dp[num][k] != -1) 16 | return dp[num][k]; 17 | ll ans = 0; 18 | for(ll i = num; i <= n; i += num) { 19 | ans = (ans % MOD + f(i, k - 1) % MOD) % MOD; 20 | } 21 | return dp[num][k] = ans; 22 | } 23 | 24 | int main() { 25 | // ll t; 26 | // cin >> t; while(t--) { 27 | cin >> n >> k; 28 | memset(dp, -1, sizeof dp); 29 | ll ans = 0; 30 | for(ll i = 1; i <= n; i++) { 31 | ans = (ans % MOD + f(i, k - 1) % MOD) % MOD; 32 | } 33 | cout << ans << endl; 34 | // } 35 | } 36 | -------------------------------------------------------------------------------- /Codeforces/431C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #define ll long long int 5 | #define MOD 1000000007 6 | #define MAX 105 7 | 8 | ll n, k, d; 9 | ll dp[MAX][2]; 10 | 11 | ll f(ll n, bool taken) { 12 | if(n == 0 && taken) 13 | return 1; 14 | if(n <= 0) 15 | return 0; 16 | if(dp[n][taken] != -1) 17 | return dp[n][taken]; 18 | ll ans = 0; 19 | for(ll i = 1; i <= k; i++) { 20 | bool tk = taken; 21 | if(i >= d) 22 | tk = 1; 23 | ans = (ans % MOD + f(n - i, tk) % MOD) % MOD; 24 | } 25 | return dp[n][taken] = ans; 26 | } 27 | 28 | int main() { 29 | // ll t; 30 | // cin >> t; while(t--) { 31 | memset(dp, -1, sizeof dp); 32 | cin >> n >> k >> d; 33 | cout << f(n, 0) << endl; 34 | // } 35 | } 36 | -------------------------------------------------------------------------------- /Codeforces/455A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #define ll long long int 5 | #define MX 100005 6 | 7 | ll dp[MX], cnt[MX]; 8 | 9 | ll f(ll n) { 10 | if(n < 0) 11 | return 0; 12 | if(dp[n] != -1) 13 | return dp[n]; 14 | ll op1 = f(n - 1); 15 | ll op2 = (n * cnt[n]) + f(n - 2); 16 | return dp[n] = max(op1, op2); 17 | } 18 | 19 | int main() { 20 | ll n, mx = -1; 21 | cin >> n; 22 | memset(cnt, 0, sizeof dp); 23 | memset(dp, -1, sizeof dp); 24 | for(ll i = 0; i < n; i++) { 25 | ll x; 26 | cin >> x; 27 | mx = max(mx, x); 28 | cnt[x]++; 29 | } 30 | cout << f(MX - 1); 31 | } 32 | -------------------------------------------------------------------------------- /Codeforces/467C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #define ll long long int 5 | #define MOD 1000000007 6 | #define MAX 5001 7 | 8 | ll n, m, k; 9 | ll a[MAX]; 10 | ll dp[MAX][MAX]; 11 | 12 | ll f(ll i, ll k) { 13 | if(i >= n) { 14 | if(k == 0) 15 | return 0; 16 | return -1e8; 17 | } 18 | if(k == 0) 19 | return 0; 20 | if(dp[i][k] != -1) 21 | return dp[i][k]; 22 | ll op1 = f(i + 1, k); 23 | ll op2 = 0; 24 | if(i + m <= n) 25 | op2 = a[i + m - 1] - (i > 0 ? a[i - 1] : 0) + f(i + m, k - 1); 26 | return dp[i][k] = max(op1, op2); 27 | } 28 | 29 | int main() { 30 | cin >> n >> m >> k; 31 | ll sum = 0; 32 | memset(dp, -1, sizeof dp); 33 | for(int i = 0; i < n; i++) { 34 | cin >> a[i]; 35 | sum += a[i]; 36 | a[i] = sum; 37 | } 38 | cout << f(0, k); 39 | } 40 | -------------------------------------------------------------------------------- /Codeforces/474D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #define ll long long int 5 | #define MOD 1000000007 6 | #define MAX 100005 7 | 8 | 9 | ll t, k; 10 | 11 | ll f(ll a) { 12 | if(a == 0) { 13 | return 1; 14 | } 15 | if(a < 0) { 16 | return 0; 17 | } 18 | return f(a - 1) + f(a - k); 19 | } 20 | 21 | int main() { 22 | cin >> t >> k; 23 | ll dp[MAX]; 24 | memset(dp, 0, sizeof dp); 25 | dp[0] = 1; 26 | for(int i = 1; i <= MAX; i++) { 27 | dp[i] = dp[i - 1] % MOD; 28 | if(i >= k) 29 | dp[i] = (dp[i] % MOD + dp[i - k] % MOD) % MOD; 30 | } 31 | for(int i = 1; i <= MAX; i++) { 32 | dp[i] = (dp[i - 1] % MOD + dp[i] % MOD) % MOD; 33 | } 34 | while(t--) { 35 | ll a, b; 36 | cin >> a >> b; 37 | cout << (dp[b] - dp[a - 1] + MOD) % MOD << endl; 38 | } 39 | // cout << f(1) << " " << f(2) << " " << f(3) << " " << f(4) << endl; 40 | } 41 | -------------------------------------------------------------------------------- /Coding Ninjas/Flags.cpp: -------------------------------------------------------------------------------- 1 | // 1B, 2W, 3R 2 | 3 | long long f(int n, int prev, int prevprev) { 4 | if(n == 1 && prevprev == 4) 5 | return 2; 6 | if(n == 1) 7 | return 1; 8 | if(prev == 1) { 9 | if(prevprev == 2) 10 | return f(n - 1, 3, prev); 11 | else 12 | return f(n - 1, 2, prev); 13 | } 14 | else if(prev == 2) { 15 | return f(n - 1, 1, prev) + f(n - 1, 3, prev); 16 | } 17 | else if(prev == 3) { 18 | return f(n - 1, 1, prev) + f(n - 1, 2, prev); 19 | } 20 | else 21 | return f(n - 1, 2, prev) + f(n - 1, 3, prev); 22 | } 23 | 24 | long long find_Ways(int N) { 25 | return f(N, 5, 4); 26 | } 27 | 28 | -------------------------------------------------------------------------------- /Coding Ninjas/ShortestSubsequence.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Gary has two string S and V. Now Gary wants to know the length shortest 3 | subsequence in S such that it is not a subsequence in V. 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | int func(string s,string t, vector>& dp) { 10 | if(s.empty()) 11 | return 1000000; 12 | if(t.empty()) 13 | return 1; 14 | int n = s.length(), m = t.length(); 15 | if(dp[n][m] != -1) 16 | return dp[n][m]; 17 | int option1 = func(s.substr(1), t, dp); 18 | int i; 19 | for(i=0; i> dp(n + 1, vector(m + 1, -1)); 33 | return func(s, t, dp); 34 | } 35 | -------------------------------------------------------------------------------- /Geeks For Geeks/Cutted Segments.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define ll long long int 3 | using namespace std; 4 | 5 | int x, y, z, dp[4001]; 6 | 7 | int maxCuts(int n) { 8 | if(n == 0) 9 | return 0; 10 | if(n < 0) 11 | return -1e5; 12 | if(dp[n] != -1) 13 | return dp[n]; 14 | int op1 = maxCuts(n - x), op2 = maxCuts(n - y), 15 | op3 = maxCuts(n - z); 16 | return dp[n] = 1 + max(op1, max(op2, op3)); 17 | } 18 | 19 | int main() { 20 | int t; 21 | cin >> t; 22 | while(t--) { 23 | memset(dp, -1, sizeof dp); 24 | int n; 25 | cin >> n >> x >> y >> z; 26 | cout << maxCuts(n) << endl; 27 | } 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /Geeks For Geeks/Distinct Subsequences Sum In An Array.cpp: -------------------------------------------------------------------------------- 1 | // Find all distinct subset (or subsequence) sums of an array 2 | // Can be done using DP if Sum * n --> <= 10^7 3 | #include 4 | using namespace std; 5 | 6 | void printDistSubsetSum(vector& arr, int n) { 7 | int sum = 0; 8 | for (int i = 0; i < n; i++) { 9 | sum += arr[i]; 10 | } 11 | bool dp[n + 1][sum + 1]; 12 | // Base case: There is always a subset with sum 0 13 | for (int i = 0; i <= n; i++) { 14 | dp[i][0] = true; 15 | } 16 | for (int i = 1; i <= n; i++) { 17 | // Always true if we have only this element 18 | dp[i][arr[i - 1]] = true; 19 | for (int j = 1; j <= sum; j++) { 20 | // If j sum was achievable till index i - 1, then 21 | // both j & (j + arr[i]) are achievable till index i 22 | if (dp[i - 1][j]) { 23 | dp[i][j] = d[i][j + arr[i - 1]] = true; 24 | } 25 | } 26 | } 27 | 28 | for (int j = 0; j <= sum; j++) { 29 | if (dp[n][j]) 30 | cout << j << " "; 31 | } 32 | cout << endl; 33 | } 34 | -------------------------------------------------------------------------------- /Geeks For Geeks/Elements With Left Side Smaller And Right Side Greater.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define ll long long int 3 | using namespace std; 4 | 5 | int main() { 6 | int t; 7 | cin >> t; 8 | while(t--) { 9 | int n; 10 | cin >> n; 11 | vector a(n), largest(n), smallest(n); 12 | for(int i = 0; i < n; i++) { 13 | cin >> a[i]; 14 | if(i == 0) 15 | largest[i] = a[i]; 16 | if(i > 0) 17 | largest[i] = max(largest[i - 1], a[i]); 18 | } 19 | smallest[n - 1] = a[n - 1]; 20 | int ret = -1; 21 | for(int i = n - 2; i >= 0; i--) { 22 | smallest[i] = min(smallest[i + 1], a[i]); 23 | } 24 | for(int i = 1; i < n - 1; i++) { 25 | if(a[i] >= largest[i - 1] && a[i] <= smallest[i + 1]) { 26 | ret = a[i]; 27 | break; 28 | } 29 | } 30 | cout << ret << endl; 31 | } 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /Geeks For Geeks/Form A Palindrome.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define ll long long int 3 | using namespace std; 4 | 5 | int dp[41][41]; 6 | 7 | int f(string s, int i, int j) { 8 | if(i >= j) 9 | return 0; 10 | if(dp[i][j] != -1) 11 | return dp[i][j]; 12 | int ans = INT_MAX; 13 | if(s[i] == s[j]) 14 | ans = f(s, i + 1, j - 1); 15 | else 16 | ans = min(f(s, i + 1, j), f(s, i, j - 1)) + 1; 17 | return dp[i][j] = ans; 18 | } 19 | 20 | int main() { 21 | int t; 22 | cin >> t; 23 | while(t--) { 24 | memset(dp, -1, sizeof dp); 25 | string s; 26 | cin >> s; 27 | cout << f(s, 0, s.size() - 1) << endl; 28 | } 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /Geeks For Geeks/Maximum Product Subarray.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define ll long long int 3 | using namespace std; 4 | 5 | int main() { 6 | int t; 7 | cin >> t; 8 | while(t--) { 9 | int n; 10 | cin >> n; 11 | vector a(n); 12 | for(int i = 0; i < n; i++) { 13 | cin >> a[i]; 14 | } 15 | ll maxPro = a[0], minPro = a[0], ret = maxPro; 16 | for(int i = 1; i < n; i++) { 17 | if(a[i] < 0) 18 | swap(maxPro, minPro); 19 | maxPro = max(a[i], maxPro * a[i]); 20 | minPro = min(a[i], minPro * a[i]); 21 | ret = max(ret, maxPro); 22 | } 23 | cout << ret << endl; 24 | } 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /Geeks For Geeks/Maximum Sum Without Adjacents.cpp: -------------------------------------------------------------------------------- 1 | 2 | int dp[1000001]; 3 | 4 | int f(vector& a, int i) { 5 | if(i >= a.size()) 6 | return 0; 7 | if(dp[i] != -1) 8 | return dp[i]; 9 | int prev1 = f(a, i + 2); 10 | int prev2 = f(a, i + 1); 11 | return dp[i] = 12 | max(prev2, max(prev1, prev1 + a[i])); 13 | } 14 | 15 | int main() { 16 | int t; 17 | cin >> t; 18 | while(t--) { 19 | int n; 20 | memset(dp, -1, sizeof dp); 21 | cin >> n; 22 | vector a(n); 23 | for(int i = 0; i < n; i++) 24 | cin >> a[i]; 25 | // cout << f(a, 0) << endl; 26 | if(n == 1) 27 | cout << a[0] << endl; 28 | else if(n == 2) { 29 | cout << max(a[0], a[1]) << endl; 30 | } 31 | else { 32 | int prev1 = a[0], prev2 = max(a[0], a[1]), ans = 0; 33 | for(int i = 2; i < n; i++) { 34 | ans = max(ans, max(a[i], prev1 + a[i])); 35 | ans = max(ans, prev2); 36 | prev1 = prev2; 37 | prev2 = ans; 38 | } 39 | cout << ans << endl; 40 | } 41 | } 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /Geeks For Geeks/Number of ways of scoring R runs in B balls with at most W wickets.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #define MOD 1000000007 5 | 6 | int dp[66][11][11]; 7 | 8 | int f(int R, int W, int B) { 9 | if(W < 0) 10 | return 0; 11 | if(B == 0) 12 | return (R == 0); 13 | if(dp[R][W][B] != -1) 14 | return dp[R][W][B]; 15 | int ans = f(R, W - 1, B - 1) % MOD; 16 | for(int i = 0; i <= 4; i++) { 17 | ans += f(R - i, W, B - 1); 18 | ans %= MOD; 19 | } 20 | ans += f(R - 6, W, B - 1); 21 | return dp[R][W][B] = ans % MOD; 22 | } 23 | 24 | int main() { 25 | int t; 26 | cin >> t; 27 | memset(dp, -1, sizeof dp); 28 | while(t--) { 29 | int R, W, B; 30 | cin >> R >> B >> W; 31 | cout << f(R, W, B) << endl; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Geeks For Geeks/Number of ways to partition a string into two balanced subsequences.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Given a string ‘S’ consisting of open and closed brackets, the task is find the number of ways in which each character of ‘S’ can be assigned to either a string ‘X’ or string ‘Y’ (both initially empty) such that the strings formed by X and Y are balanced. It can be assumed that ‘S’ is itself balanced. 4 | 5 | Examples: 6 | 7 | Input: S = "(())" 8 | Output: 6 9 | Valid assignments are : 10 | X = "(())" and Y = "" [All characters in X] 11 | X = "" and Y = "(())" [Nothing in X] 12 | X = "()" and Y = "()" [1st and 3rd characters in X] 13 | X = "()" and Y = "()" [2nd and 3rd characters in X] 14 | X = "()" and Y = "()" [2nd and 4th characters in X] 15 | X = "()" and Y = "()" [1st and 4th characters in X] 16 | 17 | */ 18 | 19 | #include 20 | using namespace std; 21 | 22 | int f(string s, int i, int cx, int cy) { 23 | if(i == s.size()) 24 | return (cx == 0 && cy == 0); 25 | int ans = 0; 26 | if(s[i] == '(') { 27 | ans = f(s, i + 1, cx + 1, cy) + f(s, i + 1, cx, cy + 1); 28 | } 29 | else { 30 | if(cx) 31 | ans = f(s, i + 1, cx - 1, cy); 32 | if(cy) 33 | ans += f(s, i + 1, cx, cy - 1); 34 | 35 | } 36 | return ans; 37 | } 38 | 39 | int main() { 40 | int t; 41 | cin >> t; 42 | while(t--) { 43 | string s; 44 | cin >> s; 45 | cout << f(s, 0, 0, 0) << endl; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Hackerrank/Construct The Array.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #define int long long int 5 | 6 | const int MOD = 1e9 + 7; 7 | 8 | signed main() { 9 | int n, k, x; 10 | cin >> n >> k >> x; 11 | int dp[n + 1][2]; 12 | if(x == 1) { 13 | dp[1][1] = 1; 14 | dp[1][0] = 0; 15 | } 16 | else { 17 | dp[1][0] = 1; 18 | dp[1][1] = 0; 19 | } 20 | for(int i = 2; i <= n; i++) { 21 | dp[i][1] = dp[i - 1][0] % MOD; 22 | dp[i][0] = ((k - 1) * (dp[i - 1][0] + dp[i - 1][1])) % MOD; 23 | dp[i][0] = (dp[i][0] - dp[i][1] + MOD) % MOD; 24 | } 25 | cout << dp[n][1]; 26 | } 27 | -------------------------------------------------------------------------------- /Hackerrank/Sherlock And Costs.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int dp[2][100001]; 5 | 6 | int cost(vector& B, int i = 0, int prev = -1) { 7 | 8 | if(i == B.size()) return 0; 9 | if(prev == -1) { 10 | return max(cost(B, i + 1, 1), cost(B, i + 1, 0)); 11 | } 12 | if(dp[prev][i] != -1) return dp[prev][i]; 13 | int ele = 1; 14 | if(prev == 0) ele = B[i - 1]; 15 | int op1 = abs(B[i] - ele) + cost(B, i + 1, 0); 16 | int op2 = abs(1 - ele) + cost(B, i + 1, 1); 17 | return dp[prev][i] = max(op1, op2); 18 | } 19 | 20 | int main() 21 | { 22 | int t; 23 | cin >> t; 24 | while(t--) { 25 | memset(dp, -1, sizeof dp); 26 | int n; 27 | cin >> n; 28 | vector B(n); 29 | for(int i = 0; i < n; i++) cin >> B[i]; 30 | int result = cost(B); 31 | cout << result << endl; 32 | } 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /Hackerrank/Stock Maximize.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define int long long int 4 | 5 | 6 | signed main() { 7 | int t; 8 | cin >> t; 9 | while(t--) { 10 | int n; 11 | cin >> n; 12 | vector a(n); 13 | stack stk; 14 | for(int i = 0; i < n; i++) cin >> a[i]; 15 | vector grt(n, -1); 16 | for(int i = 0; i < n; i++) { 17 | while(!stk.empty() && a[i] >= a[stk.top()]) { 18 | grt[stk.top()] = a[i]; 19 | stk.pop(); 20 | } 21 | stk.push(i); 22 | } 23 | int ans = 0, cnt = 0; 24 | for(int i = 0; i < n; i++) { 25 | if(grt[i] != -1) { 26 | cnt++; 27 | ans -= a[i]; 28 | } 29 | else { 30 | ans += (a[i] * cnt); 31 | cnt = 0; 32 | } 33 | } 34 | cout << ans << endl; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /InterviewBit/ArrangeII.cpp: -------------------------------------------------------------------------------- 1 | int f(string s, int i, int k, vector>& dp) { 2 | if(i == s.size()) { 3 | return k == 0 ? 0 : 1e9; 4 | } 5 | if(dp[i][k] != -1) 6 | return dp[i][k]; 7 | int ans = INT_MAX; 8 | int nW = 0, nB = 0; 9 | for(int j = i; j < s.size(); j++) { 10 | if(s[j] == 'W') 11 | nW++; 12 | else 13 | nB++; 14 | if(k) { 15 | int curr = (nW * nB) + f(s, j + 1, k - 1, dp); 16 | ans = min(ans, curr); 17 | } 18 | } 19 | if(!k) 20 | return (nW * nB); 21 | return dp[i][k] = ans; 22 | } 23 | 24 | int Solution::arrange(string A, int B) { 25 | if(B > A.size()) 26 | return -1; 27 | vector> dp(A.size() + 1, vector(B + 1, -1)); 28 | return f(A, 0, B - 1, dp); 29 | } 30 | 31 | -------------------------------------------------------------------------------- /InterviewBit/BestTimeToBuyAndSellStocksI.cpp: -------------------------------------------------------------------------------- 1 | int Solution::maxProfit(const vector &A) { 2 | int n = A.size(); 3 | int mn = INT_MAX; 4 | int maxDiff = 0; 5 | for(int i=0; i &A) { 2 | int ans = 0; 3 | /* 4 | // My Solution 5 | // d - c + c - b + b - a = d - a 6 | for(int i=1; i= A[i+1]) 15 | i++; 16 | valley = A[i]; 17 | while(i < A.size() - 1 && A[i] <= A[i+1]) 18 | i++; 19 | peak = A[i]; 20 | ans += (peak - valley); 21 | } 22 | return ans; 23 | } 24 | 25 | -------------------------------------------------------------------------------- /InterviewBit/BestTimeToBuyAndSellStocksIII.cpp: -------------------------------------------------------------------------------- 1 | int dp[100001][2][3]; 2 | 3 | int buySell(const vector &A, int i, bool buy, int trans) { 4 | if(i == A.size() || !trans) { 5 | return 0; 6 | } 7 | if(dp[i][buy][trans] != -1) 8 | return dp[i][buy][trans]; 9 | if(buy) { 10 | int option1 = buySell(A, i + 1, buy ^ 1, trans) - A[i]; 11 | int option2 = buySell(A, i + 1, buy, trans); 12 | dp[i][buy][trans] = max(option1, option2); 13 | } 14 | else { 15 | int option1 = buySell(A, i + 1, buy ^ 1, trans - 1) + A[i]; 16 | int option2 = buySell(A, i + 1, buy, trans); 17 | dp[i][buy][trans] = max(option1, option2); 18 | } 19 | return dp[i][buy][trans]; 20 | } 21 | 22 | int Solution::maxProfit(const vector &A) { 23 | memset(dp, - 1, sizeof dp); 24 | return max(buySell(A, 0, 1, 2), 0); 25 | } 26 | 27 | -------------------------------------------------------------------------------- /InterviewBit/BestTimeToBuyAndSellStocksIIIOptimized.cpp: -------------------------------------------------------------------------------- 1 | int Solution::maxProfit(const vector &A) { 2 | int a[4]; 3 | a[0] = INT_MIN, a[1] = 0, a[2] = INT_MIN, a[3] = 0; 4 | for(auto curr : A) { 5 | a[0] = max(a[0], 0 - curr); 6 | a[1] = max(a[1], a[0] + curr); 7 | a[2] = max(a[2], a[1] - curr); 8 | a[3] = max(a[3], a[2] + curr); 9 | } 10 | return max(a[1], a[3]); 11 | } 12 | -------------------------------------------------------------------------------- /InterviewBit/CoinSumInfinite.cpp: -------------------------------------------------------------------------------- 1 | #define MOD 1000007 2 | 3 | int coinWays(vector &A, int m, int i) { 4 | if(m == 0) 5 | return 1; 6 | if(i == A.size() || m < 0) 7 | return 0; 8 | int ans = coinWays(A, m, i + 1) + coinWays(A, m - A[i], i); 9 | return ans; 10 | } 11 | 12 | int Solution::coinchange2(vector &A, int B) { 13 | int n = A.size(); 14 | vector dp(B + 1, 0); 15 | dp[0] = 1; 16 | for(int i = 0; i < n; i++) { 17 | for(int j = A[i]; j <= B; j++) { 18 | dp[j] = (dp[j] % MOD + dp[j - A[i]] % MOD) % MOD; 19 | } 20 | } 21 | return dp[B]; 22 | } 23 | 24 | -------------------------------------------------------------------------------- /InterviewBit/CoinsInALine.cpp: -------------------------------------------------------------------------------- 1 | int f(vector& A, int i, int j, bool me, vector>& dp) { 2 | if(dp[i][j] != -1) 3 | return dp[i][j]; 4 | if(i == j) 5 | return 0; 6 | if(me) { 7 | int option1 = f(A, i + 1, j, 0, dp) + A[i]; 8 | int option2 = f(A, i, j - 1, 0, dp) + A[j]; 9 | return dp[i][j] = max(option1, option2); 10 | } 11 | else { 12 | int option1 = f(A, i + 1, j, 1, dp); 13 | int option2 = f(A, i, j - 1, 1, dp); 14 | return dp[i][j] = min(option1, option2); 15 | } 16 | } 17 | 18 | int Solution::maxcoin(vector &A) { 19 | vector> dp(A.size(), vector(A.size(), -1)); 20 | return f(A, 0, A.size() - 1, 1, dp); 21 | } 22 | 23 | -------------------------------------------------------------------------------- /InterviewBit/CountPermuatationsOfBST.cpp: -------------------------------------------------------------------------------- 1 | /*#define ll long long int 2 | #define MOD 1000000007 3 | 4 | ll dp[51][51]; 5 | ll choose[102][102]; 6 | 7 | void build(int N) { 8 | choose[0][0] = 1; 9 | for(int i = 1; i <= 2 * N; i++) { 10 | choose[i][0] = 1; 11 | for(int j = 1; j <= i; j++) { 12 | choose[i][j] = (choose[i - 1][j] % MOD + choose[i - 1][j - 1] % MOD) % MOD; 13 | } 14 | } 15 | } 16 | 17 | ll ways(int N, int M) { 18 | if(M < 0) 19 | return 0; 20 | if(N <= 1) 21 | return (M == 0); 22 | ll ret = dp[N][M]; 23 | if(ret != -1) 24 | return ret; 25 | ret = 0; 26 | for(int i = 1; i <= N; i++) { 27 | int x = i - 1, y = N - x - 1; 28 | 29 | for(int j = 0; j <= M - 2; j++) { 30 | ret = ret % MOD + (ways(x, j) % MOD * ways(y, M - 1) % MOD) % MOD; 31 | ret = ret % MOD + (ways(x, M - 1) % MOD * ways(y, j) % MOD) % MOD; 32 | } 33 | ret = ret % MOD + (ways(x, M - 1) % MOD * ways(y, M - 1) % MOD) % MOD; 34 | ret = (ret % MOD * choose[x + y][x] % MOD) % MOD; 35 | return dp[N][M] = ret; 36 | } 37 | } 38 | 39 | int Solution::cntPermBST(int N, int M) { 40 | memset(dp, -1, sizeof dp); 41 | memset(choose, 0, sizeof choose); 42 | build(N); 43 | return (int)ways(N, M); 44 | } 45 | */ 46 | 47 | #define MOD 1000000007ll 48 | typedef long long LL; 49 | 50 | //adds y to x, modulo MOD 51 | void add(int &x, int y){ 52 | x += y; 53 | if(x>=MOD)x-=MOD; 54 | } 55 | 56 | //choose and dp tables 57 | vector< vector > choose,dp; 58 | 59 | //build choose table 60 | void build(int N){ 61 | choose[0][0]=1; 62 | for(int i=1; i<=2*N; i++){ 63 | choose[i][0]=1; 64 | for(int j=1; j<=i; j++){ 65 | choose[i][j]=choose[i-1][j]; 66 | add(choose[i][j], choose[i-1][j-1]); 67 | } 68 | } 69 | } 70 | 71 | //reccurence function as defined in hint_2 72 | int rec(int n, int h){ 73 | if(n<=1)return (h==0); 74 | if(h<0)return 0; 75 | int &ret=dp[n][h]; 76 | if(ret!=-1)return ret; 77 | ret=0; 78 | int x, y; 79 | for(int i=1; i<=n; i++){ 80 | x=i-1; 81 | y=n-x-1; 82 | int sum1=0,sum2=0,ret1=0; 83 | for(int j=0; j<=h-2; j++) { 84 | add(sum1, rec(x, j)); 85 | add(sum2, rec(y, j)); 86 | } 87 | add(ret1, ((LL)sum1*(LL)rec(y, h-1))%MOD); 88 | add(ret1, ((LL)sum2*(LL)rec(x, h-1))%MOD); 89 | add(ret1, ((LL)rec(x, h-1)*(LL)rec(y, h-1))%MOD); 90 | ret1 = ((LL)ret1*(LL)choose[x+y][y])%MOD; 91 | add(ret, ret1); 92 | } 93 | return ret; 94 | } 95 | 96 | int Solution::cntPermBST(int A, int B) { 97 | int n=50; 98 | choose.clear(); 99 | dp.clear(); 100 | choose.resize(2*n+1,vector(2*n+1, 0)); 101 | dp.resize(n+1,vector(n+1, -1)); 102 | build(n); 103 | return rec(A, B); 104 | } 105 | 106 | -------------------------------------------------------------------------------- /InterviewBit/DecodeString.cpp: -------------------------------------------------------------------------------- 1 | string recur(string s, int& i) { 2 | int num = 0; 3 | string word = ""; 4 | for(; i < s.size(); i++) { 5 | if(s[i] == '[') { 6 | string curStr = recur(s, ++i); 7 | while(num--) 8 | word += curStr; 9 | } 10 | else if(s[i] >= '0' && s[i] <= '9') { 11 | num = num * 10 + (s[i] - '0'); 12 | } 13 | else if(s[i] == ']') { 14 | return word; 15 | } 16 | else { 17 | word += s[i]; 18 | } 19 | } 20 | return word; 21 | } 22 | 23 | string helper(int& pos, string s) { 24 | int num=0; 25 | string word = ""; 26 | for(;pos0;num--) word += curStr; 31 | } else if (cur >= '0' && cur <='9') { 32 | num = num*10 + cur - '0'; 33 | } else if (cur == ']') { 34 | return word; 35 | } else { // Normal characters 36 | word += cur; 37 | } 38 | } 39 | return word; 40 | } 41 | 42 | string Solution::solve(string A) { 43 | int i = 0; 44 | return helper(i, A); 45 | } 46 | 47 | -------------------------------------------------------------------------------- /InterviewBit/DistinctSubsequences.cpp: -------------------------------------------------------------------------------- 1 | int distSubs(string s, string t, int i, int j, int m, int n, vector>& dp) { 2 | if(j == n) 3 | return 1; 4 | if(i == m) 5 | return 0; 6 | if(dp[i][j] != -1) 7 | return dp[i][j]; 8 | if(s[i] == t[j]) { 9 | return dp[i][j] = distSubs(s, t, i + 1, j + 1, m, n, dp) + 10 | distSubs(s, t, i + 1, j, m, n, dp); 11 | } 12 | return dp[i][j] = distSubs(s, t, i + 1, j, m, n, dp); 13 | } 14 | 15 | int Solution::numDistinct(string A, string B) { 16 | vector> dp(A.size() + 1, vector(B.size() + 1, -1)); 17 | return distSubs(A, B, 0, 0, A.size(), B.size(), dp); 18 | } 19 | 20 | -------------------------------------------------------------------------------- /InterviewBit/DungeonPrincess.cpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | #define ll long long int 4 | 5 | ll f(vector>& A, int i, int j, vector>& dp) { 6 | if(i == A.size() - 1 && j == A[0].size() - 1) { 7 | return 1 - (A[i][j] < 0 ? A[i][j] : 0); 8 | } 9 | if(i >= A.size() || j >= A[0].size()) 10 | return INT_MAX; 11 | if(dp[i][j] != -1) 12 | return dp[i][j]; 13 | ll option1 = max(-A[i][j] + f(A, i + 1, j, dp), 1ll); 14 | ll option2 = max(-A[i][j] + f(A, i, j + 1, dp), 1ll); 15 | return dp[i][j] = min(option1, option2); 16 | } 17 | 18 | int Solution::calculateMinimumHP(vector > &A) { 19 | vector> dp(A.size(), vector(A[0].size(), -1)); 20 | return (int)f(A, 0, 0, dp); 21 | } 22 | 23 | 24 | -------------------------------------------------------------------------------- /InterviewBit/EditDistance.cpp: -------------------------------------------------------------------------------- 1 | int minDist(string A, string B, vector>& dp) { 2 | if(!B.size()) 3 | return A.size(); 4 | if(!A.size()) 5 | return B.size(); 6 | if(dp[A.size()][B.size()] != -1) 7 | return dp[A.size()][B.size()]; 8 | int option1 = minDist(A.substr(0, A.size() - 1), 9 | B.substr(0, B.size() - 1), dp); 10 | int option2 = minDist(A.substr(0, A.size() - 1), B, dp); 11 | int option3 = minDist(A, B.substr(0, B.size() - 1), dp); 12 | int ans; 13 | if(A.back() == B.back()) 14 | ans = option1; 15 | else 16 | ans = 1 + min(option1, min(option2, option3)); 17 | return dp[A.size()][B.size()] = ans; 18 | } 19 | 20 | int Solution::minDistance(string A, string B) { 21 | vector> dp(A.size() + 1, vector(B.size() + 1, -1)); 22 | return minDist(A, B, dp); 23 | } 24 | 25 | -------------------------------------------------------------------------------- /InterviewBit/EqualAveragePartition.cpp: -------------------------------------------------------------------------------- 1 | bool cmp(vector A, vector B) { 2 | if(A.size() == B.size()) 3 | return A < B; 4 | return A.size() < B.size(); 5 | } 6 | 7 | int partitionSet(vector &A, int start, int end, int s1, int sum, vector& v, vector& v1) { 8 | if(start == end) { 9 | if(v.size()) { 10 | if((s1 * (A.size() - v.size())) == ((sum - s1) * (v.size()))) { 11 | v1 = v; 12 | return 1; 13 | } 14 | } 15 | return 0; 16 | } 17 | int option1 = partitionSet(A, start + 1, end, s1, sum, v, v1); 18 | v.push_back(A[start]); 19 | int option2 = partitionSet(A, start + 1, end, s1 + A[start], sum, v, v1); 20 | v.pop_back(); 21 | return option1 || option2; 22 | } 23 | 24 | vector > Solution::avgset(vector &A) { 25 | int n = A.size(); 26 | int sum = 0; 27 | for(int i=0; i v; 30 | vector v1; 31 | vector> res; 32 | if(partitionSet(A, 0, n-1, 0, sum, v, v1)) { 33 | sort(v1.begin(), v1.end()); 34 | res.push_back(v1); 35 | vector v2; 36 | for(int i=0; i f(string s, int i, int j, vector>>& dp) { 4 | if(j == i) { 5 | if(s[j] == 'T') 6 | return { 1, 0 }; 7 | return { 0, 1 }; 8 | } 9 | pair p = { -1, -1 }; 10 | if(dp[i][j] != p) { 11 | return dp[i][j]; 12 | } 13 | pair ret = { 0, 0 }; 14 | for(int k = i; k <= j; k++) { 15 | if(s[k] == '&' || s[k] == '^' || s[k] == '|') { 16 | auto l = f(s, i, k - 1, dp), r = f(s, k + 1, j, dp); 17 | if(s[k] == '&') { 18 | ret.first += l.first * r.first; 19 | ret.second += l.second * r.first 20 | + r.second * (l.first + l.second); 21 | } 22 | else if(s[k] == '|') { 23 | ret.second += l.second * r.second; 24 | ret.first += l.first * (r.first + r.second) 25 | + r.first * l.second; 26 | } 27 | else if(s[k] == '^') { 28 | ret.first += l.second * r.first + r.second * l.first; 29 | ret.second += l.first * r.first 30 | + r.second * l.second; 31 | } 32 | ret.first %= MOD; ret.second %= MOD; 33 | } 34 | } 35 | return dp[i][j] = ret; 36 | } 37 | 38 | int Solution::cnttrue(string A) { 39 | int n = A.size(); 40 | vector>> dp(n, vector>(n, { -1, -1 })); 41 | return f(A, 0, A.size() - 1, dp).first; 42 | } 43 | 44 | -------------------------------------------------------------------------------- /InterviewBit/FlipArray.cpp: -------------------------------------------------------------------------------- 1 | int Solution::solve(const vector &A) { 2 | int n = A.size(); 3 | int sum = 0; 4 | for(int i=0; i dp[n + 1][capacity + 1]; 10 | 11 | for(int i=0; i<=n; i++) { 12 | for(int j=0; j<= capacity; j++) { 13 | if(i == 0 || j == 0) 14 | dp[i][j] = { 0, 0 }; 15 | else { 16 | int prevWeight = dp[i-1][j].first; 17 | int prevItems = dp[i-1][j].second; 18 | 19 | if(j - A[i-1] >= 0) { 20 | int currWeight = dp[i-1][j-A[i-1]].first + A[i-1]; 21 | int currItems = dp[i-1][j-A[i-1]].second + 1; 22 | if((currWeight > prevWeight) || 23 | (currWeight == prevWeight && currItems < prevItems)) { 24 | dp[i][j] = { currWeight, currItems }; 25 | } 26 | else 27 | dp[i][j] = dp[i-1][j]; 28 | } 29 | else 30 | dp[i][j] = dp[i-1][j]; 31 | } 32 | } 33 | } 34 | return dp[n][capacity].second; 35 | } 36 | 37 | -------------------------------------------------------------------------------- /InterviewBit/InterleavingStrings.cpp: -------------------------------------------------------------------------------- 1 | int interleave(string A, string B, string C, vector>& dp) { 2 | if(!C.size() && !A.size() && !B.size()) 3 | return 1; 4 | if(!C.size()) 5 | return 0; 6 | if(dp[A.size()][B.size()] != -1) 7 | return dp[A.size()][B.size()]; 8 | int ans = 0; 9 | if(A[0] == C[0]) 10 | ans = ans || interleave(A.substr(1), B, C.substr(1), dp); 11 | if(B[0] == C[0]) 12 | ans = ans || interleave(A, B.substr(1), C.substr(1), dp); 13 | return dp[A.size()][B.size()] = ans; 14 | } 15 | 16 | int Solution::isInterleave(string A, string B, string C) { 17 | vector> dp(A.size() + 1, vector(B.size() + 1, -1)); 18 | return interleave(A, B, C, dp); 19 | } 20 | 21 | 22 | -------------------------------------------------------------------------------- /InterviewBit/Intersecting Chords In A Circle.cpp: -------------------------------------------------------------------------------- 1 | #define MOD 1000000007 2 | #define ll long long int 3 | 4 | ll f(ll i, vector& dp) { 5 | if(i == 0 || i == 2) 6 | return 1; 7 | if(dp[i] != -1) 8 | return dp[i]; 9 | ll ans = 0; 10 | for(int k = 2; k <= i; k += 2) { 11 | ans = (ans % MOD + ((f(k - 2, dp) % MOD * f(i - k, dp)) % MOD) % MOD) % MOD; 12 | } 13 | return dp[i] = ans; 14 | } 15 | 16 | int Solution::chordCnt(int A) { 17 | vector dp(2 * A + 1, -1); 18 | return (int)f(2 * A, dp); 19 | } 20 | 21 | -------------------------------------------------------------------------------- /InterviewBit/Jesse And Two Strings.cpp: -------------------------------------------------------------------------------- 1 | /*Jesse and two string 2 | 3 | Jesse loves playing with strings, so Wanda gives him two strings, A and B, and asks him to find the length of the longest palindrome that can be fomed using the characters from two palindromic subsequences such that one palindromic subsequence is chosen from A and the other palindromic subsequence is chosen from B.*/ 4 | 5 | int dp[1002][1002]; 6 | int dp2[1002][1002]; 7 | 8 | int get_pal_len(string &A){ 9 | memset(dp, 0, sizeof dp); 10 | int n = A.size(); 11 | int maxm = 0; 12 | 13 | for(int len = n; len >= 2; --len){ 14 | for(int i = 1; i + len - 1 <= n; ++i){ 15 | int j = i + len - 1; 16 | if(A[i - 1] == A[j - 1]){ 17 | dp[i][j] = 2 + dp[i - 1][j + 1]; 18 | } else { 19 | dp[i][j] = max(dp[i - 1][j], dp[i][j + 1]); 20 | } 21 | maxm = max(maxm, dp[i][j]); 22 | } 23 | } 24 | 25 | for(int i = 1; i <= n; ++i){ 26 | dp[i][i] = 1 + dp[i - 1][i + 1]; 27 | maxm = max(maxm, dp[i][i]); 28 | } 29 | return maxm; 30 | } 31 | 32 | int get_pal_lenb(string &A){ 33 | memset(dp2, 0, sizeof dp2); 34 | int n = A.size(); 35 | int maxm = 0; 36 | 37 | for(int len = n; len >= 2; --len){ 38 | for(int i = 1; i + len - 1 <= n; ++i){ 39 | int j = i + len - 1; 40 | if(A[i - 1] == A[j - 1]){ 41 | dp2[i][j] = 2 + dp2[i - 1][j + 1]; 42 | } else { 43 | dp2[i][j] = max(dp2[i - 1][j], dp2[i][j + 1]); 44 | } 45 | maxm = max(maxm, dp2[i][j]); 46 | } 47 | } 48 | 49 | for(int i = 1; i <= n; ++i){ 50 | dp2[i][i] = 1 + dp2[i - 1][i + 1]; 51 | maxm = max(maxm, dp2[i][i]); 52 | } 53 | 54 | return maxm; 55 | } 56 | 57 | int Solution::solve(string A, string B) { 58 | set< char > ca(A.begin(), A.end()); 59 | set< char > cb(B.begin(), B.end()); 60 | 61 | int ansa = get_pal_len(A); 62 | int ansb = get_pal_lenb(B); 63 | 64 | if(ansa % 2 == 0 or ansb % 2 == 0){ 65 | return ansa + ansb; 66 | } else { 67 | int n = A.size(); 68 | int m = B.size(); 69 | 70 | for(int i = 1; i <= n; ++i){ 71 | for(int j = 1; j <= m; ++j){ 72 | if(A[i - 1] == B[j - 1] and dp[i][i] == ansa and dp2[j][j] == ansb){ 73 | return ansa + ansb; 74 | } 75 | } 76 | } 77 | 78 | return ansa + ansb - 1; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /InterviewBit/JumpGameArray.cpp: -------------------------------------------------------------------------------- 1 | int Solution::canJump(vector &A) { 2 | int last = A.size() - 1; 3 | for(int i = A.size() - 2; i >= 0; i--) { 4 | if(i + A[i] >= last) 5 | last = i; 6 | } 7 | return (last <= 0); 8 | } 9 | 10 | -------------------------------------------------------------------------------- /InterviewBit/Kingdom War.cpp: -------------------------------------------------------------------------------- 1 | int Solution::solve(vector > &A) { 2 | int n = A.size(), m = A[0].size(), mx = INT_MIN; 3 | vector prev(m + 1, 0), dp(m + 1, 0); 4 | // vector> dp(n + 1, vector(m + 1, 0)); 5 | for(int i = n - 1; i >= 0; i--) { 6 | for(int j = m - 1; j >= 0; j--) { 7 | dp[j] = A[i][j] + prev[j] + dp[j + 1] - prev[j + 1]; 8 | // dp[i][j] = A[i][j] + dp[i + 1][j] + dp[i][j + 1] - dp[i + 1][j + 1]; 9 | // mx = max(mx, dp[i][j]); 10 | mx = max(mx, dp[j]); 11 | } 12 | prev = dp; 13 | } 14 | return mx; 15 | } 16 | 17 | -------------------------------------------------------------------------------- /InterviewBit/KthManhattanDistanceNeigbhourhood.cpp: -------------------------------------------------------------------------------- 1 | // int dp[301][301][301]; 2 | 3 | /*int f(vector>& B, int i, int j, int k) { 4 | if(i < 0 || j < 0 || i >= B.size() || j >= B[0].size()) 5 | return 0; 6 | if(k == 0) 7 | return B[i][j]; 8 | if(dp[i][j][k] != -1) 9 | return dp[i][j][k]; 10 | int mx = B[i][j]; 11 | mx = max(f(B, i - 1, j, k - 1), mx); 12 | mx = max(f(B, i + 1, j, k - 1), mx); 13 | mx = max(f(B, i, j - 1, k - 1), mx); 14 | mx = max(f(B, i, j + 1, k - 1), mx); 15 | return dp[i][j][k] = mx; 16 | }*/ 17 | 18 | vector > Solution::solve(int A, vector > &B) { 19 | if(!A) 20 | return B; 21 | vector> ret = B; 22 | int n = B.size(), m = B[0].size(); 23 | for(int k = 1; k <= A; k++) { 24 | for(int i = 0; i < n; i++) { 25 | for(int j = 0; j < m; j++) { 26 | if(i > 0) 27 | ret[i][j] = max(ret[i][j], B[i - 1][j]); 28 | if(i < n - 1) 29 | ret[i][j] = max(ret[i][j], B[i + 1][j]); 30 | if(j > 0) 31 | ret[i][j] = max(ret[i][j], B[i][j - 1]); 32 | if(j < m - 1) 33 | ret[i][j] = max(ret[i][j], B[i][j + 1]); 34 | } 35 | } 36 | B = ret; 37 | } 38 | return ret; 39 | } 40 | 41 | -------------------------------------------------------------------------------- /InterviewBit/Largest Area Of Rectangle With Permutations.cpp: -------------------------------------------------------------------------------- 1 | bool cmp(int a, int b) { 2 | return (a > b); 3 | } 4 | 5 | int Solution::solve(vector > &A) { 6 | int n = A.size(), m = A[0].size(); 7 | vector> hist(n + 1, vector(m + 1, 0)); 8 | for(int i = 0; i < n; i++) { 9 | for(int j = 0; j < m; j++) { 10 | if(i == 0) 11 | hist[i][j] = A[i][j]; 12 | else 13 | hist[i][j] = (A[i][j]) ? 1 + hist[i - 1][j] : 0; 14 | } 15 | } 16 | for(int i = 0; i < n; i++) { 17 | sort(hist[i].begin(), hist[i].end(), cmp); 18 | } 19 | int mx = 0; 20 | for(int i = 0; i < n; i++) { 21 | for(int j = 0; j < n; j++) { 22 | mx = max(mx, hist[i][j] * (j + 1)); 23 | } 24 | } 25 | return mx; 26 | } 27 | 28 | -------------------------------------------------------------------------------- /InterviewBit/LastStoneWeightII.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int dp[31][6001]; 4 | int f(vector& s, int i, int sum) { 5 | if(i == s.size()) { 6 | if(sum < 0) 7 | return INT_MAX; 8 | return sum; 9 | } 10 | if(dp[i][sum + 3000] != -1) 11 | return dp[i][sum + 3000]; 12 | int op1 = f(s, i + 1, sum + s[i]); 13 | int op2 = f(s, i + 1, sum - s[i]); 14 | return dp[i][sum + 3000] = min(op1, op2); 15 | } 16 | 17 | int lastStoneWeightII(vector& stones) { 18 | memset(dp, -1, sizeof dp); 19 | return f(stones, 0, 0); 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /InterviewBit/Length Of Longest Subsequence.cpp: -------------------------------------------------------------------------------- 1 | int Solution::longestSubsequenceLength(const vector &A) { 2 | int n = A.size(), mx = 0; 3 | vector lis(n + 1, 1); 4 | vector lds(n + 1, 1); 5 | for(int i = 0; i < n; i++) { 6 | for(int j = i + 1; j < n; j++) { 7 | if(A[i] <= A[j] && lis[j] < lis[i] + 1) 8 | lis[j] = lis[i] + 1; 9 | } 10 | } 11 | for(int i = n - 1; i >= 0; i--) { 12 | for(int j = i - 1; j >= 0; j--) { 13 | if(A[j] >= A[i] && lds[j] < lds[i] + 1) 14 | lds[j] = lds[i] + 1; 15 | } 16 | } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /InterviewBit/Let'sParty.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Let's Party 3 | 4 | In Danceland, one person can party either alone or can pair up with another person. 5 | 6 | Can you find in how many ways they can party if there are N people in Danceland? 7 | 8 | Input Format 9 | 10 | Given only argument A of type Integer, number of people in Danceland. 11 | 12 | Output Format 13 | 14 | Return a single integer N mod 10003, i.e number of ways people of Danceland can party. 15 | 16 | Constraints 17 | 18 | 1 <= N <= 1e5 19 | 20 | Example 21 | 22 | Input: 23 | N = 3 24 | 25 | Output : 26 | 4 27 | 28 | Explanation : 29 | Let suppose three people are A, B, and C. 30 | There are only 4 ways to party as, 31 | (A, B, C) All party alone 32 | (AB, C) A and B party together and C party alone 33 | (AC, B) A and C party together and B party alone 34 | (BC, A) B and C party together and A party alone 35 | here 4 % 10003 = 4, so answer is 4. 36 | 37 | */ 38 | 39 | #define MOD 10003 40 | #define ll long long int 41 | 42 | ll party(int n, vector& dp) { 43 | if(n == 0|| n == 1) 44 | return 1; 45 | if(dp[n] != -1) 46 | return dp[n]; 47 | return dp[n] = (party(n - 1, dp) % MOD + ((n - 1) % MOD * party(n - 2, dp) % MOD) % MOD) % MOD; 48 | } 49 | 50 | int Solution::solve(int A) { 51 | vector dp(A + 1, -1); 52 | dp[0] = 1, dp[1] = 1; 53 | for(int i = 2; i <= A; i++) { 54 | dp[i] = (dp[i - 1] % MOD + ((i - 1) % MOD * dp[i - 2] % MOD) % MOD) % MOD; 55 | } 56 | return (int)(dp[A]); 57 | } 58 | 59 | -------------------------------------------------------------------------------- /InterviewBit/Longest Arithmetic Progression.cpp: -------------------------------------------------------------------------------- 1 | int Solution::solve(const vector &A) { 2 | int n = A.size(), ans = 0; 3 | if(n <= 2) 4 | return n; 5 | unordered_map mp; 6 | vector> dp(n, vector(n, 0)); 7 | for(int j = n - 1; j >= 0; j--) { 8 | for(int i = j - 1; i >= 0; i--) { 9 | int diff = A[j] - A[i]; 10 | int val = A[j] + diff; 11 | if(mp.find(val) != mp.end()) { 12 | int k = mp[val]; 13 | dp[i][j] = 1 + dp[j][k]; 14 | } 15 | else 16 | dp[i][j] = 2; 17 | ans = max(ans, dp[i][j]); 18 | } 19 | mp[A[j]] = j; 20 | } 21 | return ans; 22 | } 23 | 24 | -------------------------------------------------------------------------------- /InterviewBit/Longest Valid Parentheses.cpp: -------------------------------------------------------------------------------- 1 | int Solution::longestValidParentheses(string A) { 2 | int ret = 0; 3 | vector dp(A.size(), 0); 4 | for(int i = 1; i < A.size(); i++) { 5 | if(A[i] == ')') { 6 | if(A[i - 1] == '(') { 7 | dp[i] = 2 + ((i >= 2) ? dp[i - 2] : 0); 8 | } 9 | else { 10 | int prev = i - 1 - dp[i - 1]; 11 | if(prev >= 0 && A[prev] == '(') { 12 | dp[i] = 2 + dp[i - 1] + (prev > 0 ? dp[prev - 1] : 0); 13 | } 14 | } 15 | } 16 | ret = max(ret, dp[i]); 17 | } 18 | return ret; 19 | } 20 | 21 | -------------------------------------------------------------------------------- /InterviewBit/LongestValidParentheses.cpp: -------------------------------------------------------------------------------- 1 | int Solution::longestValidParentheses(string A) { 2 | int n = A.size(); 3 | int dp[n + 1]; 4 | int mx = 0; 5 | memset(dp, 0, sizeof dp); 6 | for(int i = 1; i < n; i++) { 7 | if(A[i] == ')' && A[i - 1] == '(') { 8 | dp[i] = 2 + (i >= 2 ? dp[i - 2] : 0); 9 | } 10 | else if(A[i] == ')' && A[i - 1] == ')') { 11 | int dist = i - dp[i - 1] - 1; 12 | if(dist >= 0 && A[dist] == '(') { 13 | dp[i] = dp[i - 1] + 2 + (dist - 1 >= 0 ? dp[dist - 1] : 0); 14 | } 15 | } 16 | mx = max(mx, dp[i]); 17 | } 18 | return mx; 19 | } 20 | 21 | -------------------------------------------------------------------------------- /InterviewBit/Max Rectangle In Binary Matrix.cpp: -------------------------------------------------------------------------------- 1 | int largestRect(vector& A) { 2 | int n = A.size(); 3 | stack stk; 4 | vector left(n, -1); 5 | vector right(n, n); 6 | for(int i = 0; i < n; i++) { 7 | while(stk.size() && A[stk.top()] >= A[i]) 8 | stk.pop(); 9 | if(stk.size()) 10 | left[i] = stk.top(); 11 | stk.push(i); 12 | } 13 | while(stk.size()) 14 | stk.pop(); 15 | for(int i = n - 1; i >= 0; i--) { 16 | while(stk.size() && A[stk.top()] >= A[i]) 17 | stk.pop(); 18 | if(stk.size()) 19 | right[i] = stk.top(); 20 | stk.push(i); 21 | } 22 | int mx = 0; 23 | for(int i = 0; i < n; i++) { 24 | mx = max(mx, A[i] * (right[i] - left[i] - 1)); 25 | } 26 | return mx; 27 | } 28 | 29 | int Solution::maximalRectangle(vector > &A) { 30 | int n = A.size(), m = A[0].size(); 31 | int mx = 0; 32 | vector> dp(n, vector(m, 0)); 33 | for(int i = 0; i < n; i++) { 34 | for(int j = 0; j < m; j++) { 35 | if(A[i][j] == 0) 36 | dp[i][j] = 0; 37 | else 38 | dp[i][j] = A[i][j] + (i > 0 ? dp[i - 1][j] : 0); 39 | } 40 | mx = max(mx, largestRect(dp[i])); 41 | } 42 | return mx; 43 | } 44 | 45 | -------------------------------------------------------------------------------- /InterviewBit/MaxSumWithoutAdjacentElements.cpp: -------------------------------------------------------------------------------- 1 | int maxSum(vector>& A, int start, vector& dp) { 2 | if(start >= A[0].size()) 3 | return 0; 4 | if(dp[start] != -1) 5 | return dp[start]; 6 | int option1 = A[0][start] + maxSum(A, start + 2, dp); 7 | int option2 = A[1][start] + maxSum(A, start + 2, dp); 8 | int option3 = maxSum(A, start + 1, dp); 9 | return dp[start] = max(option1, max(option2, option3)); 10 | } 11 | 12 | int Solution::adjacent(vector > &A) { 13 | vector dp(A[0].size(), -1); 14 | return maxSum(A, 0, dp); 15 | } 16 | 17 | -------------------------------------------------------------------------------- /InterviewBit/MaximumSum.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Maximum Sum 3 | 4 | You are given an array A of N integers and three integers X, Y, and Z. 5 | 6 | You have to find the maximum value of A[i]*X + A[j]*Y + A[k]*Z, where 1 <= i <= j <= k <= N. 7 | */ 8 | 9 | int dp[100001][2][2][2]; 10 | 11 | int maxSum(vector &A, int x, int y, int z, int tx, int ty, int tz, int i) { 12 | if(i == A.size() && tx && ty && tz) 13 | return 0; 14 | if(i == A.size()) 15 | return INT_MIN; 16 | if(dp[i][tx][ty][tz] != -1) 17 | return dp[i][tx][ty][tz]; 18 | int option1 = INT_MIN, option2 = INT_MIN, option3 = INT_MIN, option4; 19 | if(!tx && !ty && !tz) 20 | option1 = A[i] * x + maxSum(A, x, y, z, 1, ty, tz, i); 21 | else if(tx && !ty && !tz) 22 | option2 = A[i] * y + maxSum(A, x, y, z, tx, 1, tz, i); 23 | else if(tx && ty && !tz) 24 | option3 = A[i] * z + maxSum(A, x, y, z, tx, ty, 1, i); 25 | option4 = maxSum(A, x, y, z, tx, ty, tz, i + 1); 26 | return dp[i][tx][ty][tz] = max(max(option1, option2), max(option3, option4)); 27 | } 28 | 29 | int Solution::solve(vector &A, int B, int C, int D) { 30 | memset(dp, -1, sizeof dp); 31 | return maxSum(A, B, C, D, 0, 0, 0, 0); 32 | } 33 | 34 | -------------------------------------------------------------------------------- /InterviewBit/MinJumpsArray.cpp: -------------------------------------------------------------------------------- 1 | int minJump(vector& A, int start, int end, vector& dp) { 2 | if(start >= end) { 3 | return 0; 4 | } 5 | if(dp[start] != -1) 6 | return dp[start]; 7 | int ans = INT_MAX; 8 | for(int i = start + 1; i <= start + A[start] && i < A.size(); i++) { 9 | int nextStep = minJump(A, i, end, dp); 10 | if(nextStep != INT_MAX) 11 | ans = min(ans, 1 + nextStep); 12 | } 13 | return dp[start] = ans; 14 | } 15 | 16 | int Solution::jump(vector &A) { 17 | int n = A.size(); 18 | vector dp(n + 1, -1); 19 | int ans = minJump(A, 0, A.size() - 1, dp); 20 | if(ans != INT_MAX) 21 | return ans; 22 | return -1; 23 | } 24 | 25 | -------------------------------------------------------------------------------- /InterviewBit/MinJumpsArray_Optimized.cpp: -------------------------------------------------------------------------------- 1 | int Solution::jump(vector &A) { 2 | if(A.size() <= 1) 3 | return 0; 4 | int level = 0; 5 | int currMax = 0, i = 0; 6 | while(i <= currMax) { 7 | int farthest = currMax; 8 | for(; i <= currMax; i++) { 9 | farthest = max(farthest, i + A[i]); 10 | if(farthest >= A.size() - 1) 11 | return level + 1; 12 | } 13 | currMax = farthest; 14 | level++; 15 | } 16 | return -1; 17 | } 18 | 19 | -------------------------------------------------------------------------------- /InterviewBit/MinSumPathInMatrix.cpp: -------------------------------------------------------------------------------- 1 | int minPath(vector>& A, int r1, int r2, int c1, int c2, 2 | vector>& dp) { 3 | if(r1 == r2 && c1 == c2) { 4 | return A[r1][c1]; 5 | } 6 | if(r1 < 0 || r1 > r2 || c1 < 0 || c1 > c2) { 7 | return INT_MAX; 8 | } 9 | if(dp[r1][c1] != -1) 10 | return dp[r1][c1]; 11 | int option1 = minPath(A, r1 + 1, r2, c1, c2, dp); 12 | int option2 = minPath(A, r1, r2, c1 + 1, c2, dp); 13 | if(option1 == INT_MAX) 14 | dp[r1][c1] = A[r1][c1] + option2; 15 | else if(option2 == INT_MAX) 16 | dp[r1][c1] = A[r1][c1] + option1; 17 | else 18 | dp[r1][c1] = A[r1][c1] + min(option1, option2); 19 | return dp[r1][c1]; 20 | } 21 | 22 | int Solution::minPathSum(vector > &A) { 23 | int m = A.size(), n = A[0].size(); 24 | vector> dp(m + 1, vector(n + 1, -1)); 25 | return minPath(A, 0, m - 1, 0, n - 1, dp); 26 | } 27 | 28 | -------------------------------------------------------------------------------- /InterviewBit/MinSumPathInTriangle.cpp: -------------------------------------------------------------------------------- 1 | int Solution::minimumTotal(vector > &A) { 2 | int n = A.size(), m = A[n - 1].size(); 3 | vector dp(m); 4 | for(int i = 0; i < m; i++) 5 | dp[i] = A[n - 1][i]; 6 | for(int i = n - 2; i >= 0; i--) { 7 | for(int j = 0; j < A[i].size(); j++) { 8 | dp[j] = min(dp[j], dp[j + 1]) + A[i][j]; 9 | } 10 | } 11 | return dp[0]; 12 | } 13 | 14 | -------------------------------------------------------------------------------- /InterviewBit/NDigitNumbersWithDigitSumS.cpp: -------------------------------------------------------------------------------- 1 | #define MOD 1000000007 2 | 3 | int f(int N, int S, vector>& dp) { 4 | if(N == 0) 5 | return (S == 0); 6 | if(dp[N][S] != -1) 7 | return dp[N][S]; 8 | int ret = 0; 9 | for(int i = 0; i <= 9 && i <= S; i++) { 10 | ret = (ret % MOD + f(N - 1, S - i, dp) % MOD) % MOD; 11 | } 12 | return dp[N][S] = ret % MOD; 13 | } 14 | 15 | int Solution::solve(int A, int B) { 16 | int ret = 0; 17 | vector> dp(A + 1, vector(B + 1, - 1)); 18 | for(int i = 1; i <= 9 && i <= B; i++) { 19 | ret = (ret % MOD + f(A - 1, B - i, dp) % MOD) % MOD; 20 | } 21 | return ret % MOD; 22 | } 23 | 24 | -------------------------------------------------------------------------------- /InterviewBit/OddPalindrome.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Odd Palindrome 3 | 4 | A palindrome string is a string which reads the same forward and backward. 5 | If a palindrome string is of odd length l, then (l+1)/2th character (1 index based) 6 | is said to be the centre of the palindrome. 7 | 8 | You are given a string A. Return an array X of integers where X[i] = 9 | (number of odd length palindrome subsequence of A with A[i] as the centre) 10 | modulo 1000000007. 11 | 12 | A subsequence of A is a string which can be derived from A by deleting 13 | some of its character.*/ 14 | 15 | #define MOD 1000000007 16 | 17 | vector Solution::solve(string A) { 18 | int n = A.size(); 19 | int dp[n][n]; 20 | memset(dp, 0, sizeof dp); 21 | for(int len = n - 1; len >= 0; len--) { 22 | for(int i = 0; i + len < n; i++) { 23 | int j = i + len; 24 | if(i == 0 && j == n - 1) { 25 | if(A[i] == A[j]) { 26 | dp[i][j] = 2; 27 | } 28 | else 29 | dp[i][j] = 1; 30 | } 31 | else { 32 | if(i - 1 >= 0) 33 | dp[i][j] = (dp[i][j] % MOD + dp[i - 1][j] % MOD ) % MOD; 34 | if(j + 1 <= n - 1) 35 | dp[i][j] = (dp[i][j] % MOD + dp[i][j + 1] % MOD) % MOD; 36 | if(A[i] != A[j] && (i - 1 >= 0 && j + 1 <= n - 1)) 37 | dp[i][j] = (dp[i][j] % MOD - dp[i - 1][j + 1] % MOD + MOD) % MOD; 38 | if(A[i] == A[j] && (i - 1 < 0 || j + 1 > n - 1)) 39 | dp[i][j] = (1 % MOD+ dp[i][j] % MOD) % MOD; 40 | } 41 | } 42 | } 43 | vector ret; 44 | for(int i = 0; i < n; i++) { 45 | if(i == 0 || i == n - 1) 46 | ret.push_back(1); 47 | else 48 | ret.push_back(dp[i - 1][i + 1]); 49 | } 50 | return ret; 51 | } 52 | 53 | -------------------------------------------------------------------------------- /InterviewBit/PalindromePartitioning.cpp: -------------------------------------------------------------------------------- 1 | int pal[501][501]; 2 | int dp[501][501]; 3 | 4 | int minCuts(string A, int l, int r) { 5 | if(l == r || pal[l][r]) 6 | return 0; 7 | if(dp[l][r] != -1) 8 | return dp[l][r]; 9 | int ans = INT_MAX; 10 | for(int i = l; i < r; i++) { 11 | ans = min(ans, 1 + minCuts(A, l, i) + minCuts(A, i + 1, r)); 12 | } 13 | return dp[l][r] = ans; 14 | } 15 | 16 | int Solution::minCut(string A) { 17 | int n = A.size(); 18 | memset(pal, 0, sizeof pal); 19 | memset(dp, -1, sizeof dp); 20 | for(int i = 0; i < n; i++) 21 | pal[i][i] = 1; 22 | for(int i = 0; i < n; i++) { 23 | for(int j = i; j >= 0; j--) { 24 | if(A[i] == A[j] && (i - j < 2 || pal[j + 1][i - 1])) 25 | pal[j][i] = 1; 26 | } 27 | } 28 | return minCuts(A, 0, A.size() - 1); 29 | } 30 | 31 | -------------------------------------------------------------------------------- /InterviewBit/Queen Attack.cpp: -------------------------------------------------------------------------------- 1 | vector> dp[8]; 2 | 3 | bool valid(int i, int j, vector& A) { 4 | if(i < 0 || j < 0 || i >= A.size() || j >= A[0].size()) 5 | return 0; 6 | return 1; 7 | } 8 | 9 | int dx[8] = {-1, -1, 0, 1, 1, 1, 0, -1}; 10 | int dy[8] = {0, 1, 1, 1, 0, -1, -1, -1}; 11 | 12 | int f(int i, int j, int k, vector& A) { 13 | if(dp[k][i][j] != -1) 14 | return dp[k][i][j]; 15 | int ret = 0; 16 | int ni = i + dx[k], nj = j + dy[k]; 17 | if(valid(ni, nj, A)) { 18 | if(A[ni][nj] == '1') 19 | ret++; 20 | else 21 | ret += f(ni, nj, k, A); 22 | } 23 | return dp[k][i][j] = ret; 24 | } 25 | 26 | vector > Solution::queenAttack(vector &A) { 27 | int n = A.size(), m = A[0].size(); 28 | for(int i = 0; i < 8; i++){ 29 | dp[i].clear(); 30 | dp[i].resize(n, vector(m, -1)); 31 | } 32 | vector> ret(n, vector(m, 0)); 33 | for(int i = 0; i < n; i++) { 34 | for(int j = 0; j < m; j++) { 35 | for(int k = 0; k < 8; k++) { 36 | ret[i][j] += f(i, j, k, A); 37 | } 38 | } 39 | } 40 | return ret; 41 | } 42 | 43 | -------------------------------------------------------------------------------- /InterviewBit/RegularExpressionII.cpp: -------------------------------------------------------------------------------- 1 | /*bool ismatch(const string s, int i, const string p, int j, vector>& dp) { 2 | if(j >= p.size()) 3 | return i >= s.size(); 4 | if(i >= s.size()) { 5 | if(j < p.size() - 1 && p[j + 1] == '*') 6 | return ismatch(s, i, p, j + 2, dp); 7 | return 0; 8 | } 9 | if(dp[i][j] != -1) 10 | return dp[i][j]; 11 | if(j < p.size() - 1 && p[j + 1] == '*') { 12 | // Skip this character from pattern 13 | bool option1 = ismatch(s, i, p, j + 2, dp); 14 | // Skip a sequence of characters of string if they match curr char 15 | // of pattern 16 | bool option2 = ((s[i] == p[j] || p[j] == '.') && 17 | ismatch(s, i + 1, p, j, dp)); 18 | return dp[i][j] = option1 || option2; 19 | } 20 | if(s[i] == p[j] || p[j] == '.') 21 | return dp[i][j] = ismatch(s, i + 1, p, j + 1, dp); 22 | return 0; 23 | }*/ 24 | 25 | 26 | int Solution::isMatch(const string s, const string p) { 27 | // vector> dp(A.size() + 1, vector(B.size() + 1, -1)); 28 | // return ismatch(A, 0, B, 0, dp); 29 | int m = s.size(), n = p.size(); 30 | vector pre(n + 1, false), cur(n + 1, false); 31 | cur[0] = true; 32 | for (int i = 0; i <= m; i++) { 33 | for (int j = 1; j <= n; j++) { 34 | if (p[j - 1] == '*') { 35 | cur[j] = cur[j - 2] || (i && pre[j] && (s[i - 1] == p[j - 2] || p[j - 2] == '.')); 36 | } else { 37 | cur[j] = i && pre[j - 1] && (s[i - 1] == p[j - 1] || p[j - 1] == '.'); 38 | } 39 | } 40 | fill(pre.begin(), pre.end(), false); 41 | swap(pre, cur); 42 | } 43 | return pre[n]; 44 | } 45 | 46 | -------------------------------------------------------------------------------- /InterviewBit/RegularExpressionMatch.cpp: -------------------------------------------------------------------------------- 1 | int Solution::isMatch(const string A, const string B) { 2 | int m = A.size(), n = B.size(); 3 | vector> dp(m + 1, vector(n + 1, 0)); 4 | for(int i = 0; i <= m; i++) { 5 | for(int j = 0; j <= n; j++) { 6 | if(i == 0 && j == 0) 7 | dp[i][j] = 1; 8 | else if(i == 0 && B[j - 1] == '*') { 9 | dp[i][j] = dp[i][j - 1]; 10 | } 11 | else if(i == 0 || j == 0) 12 | dp[i][j] = 0; 13 | else if(A[i - 1] == B[j - 1] || B[j - 1] == '?') 14 | dp[i][j] = dp[i - 1][j - 1]; 15 | else if(B[j - 1] == '*') 16 | dp[i][j] = dp[i - 1][j] || dp[i][j - 1]; 17 | } 18 | } 19 | return dp[m][n]; 20 | } 21 | 22 | -------------------------------------------------------------------------------- /InterviewBit/Remove The Substring.cpp: -------------------------------------------------------------------------------- 1 | /*Remove the Substring 2 | 3 | Given 2 strings of lowercase alphabets A and B of size N and M respectively. 4 | 5 | it is guaranteed that B is a subsequence of A. 6 | 7 | For example, the strings "test", "tst", "tt", "et" and "" are subsequences of the string "test". But the strings "tset", "se", "contest" are not subsequences of the string "test". 8 | 9 | You need to remove some substring(contiguous subsequence) from A of maximum possible length such that after removing this substring B will remain a subsequence of A. 10 | 11 | If you want to remove the substring A[l::r] then the string A will be transformed to A1A2…Al−1Ar+1Ar+2…A|A|−1A|A| (where |A| is the length of A). 12 | 13 | Find and return the maximum possible length of the substring you can remove so that B is still a subsequence of A.*/ 14 | 15 | int Solution::solve(string s, string t) { 16 | int n = t.size(), m = s.size(); 17 | vector l(n, -1), r(n, s.size()); 18 | int i = 0; 19 | for(int j = 0; j < s.size(); j++) { 20 | if(t[i] == s[j]) { 21 | l[i] = j; 22 | i++; 23 | } 24 | } 25 | i = n - 1; 26 | for(int j = s.size() - 1; j >= 0; j--) { 27 | if(t[i] == s[j]) { 28 | r[i] = j; 29 | i--; 30 | } 31 | } 32 | int ans = r[0]; 33 | for(int i = 0; i < n - 1; i++) { 34 | // cout << l[i] << " " << r[i + 1] << " "; 35 | ans = max(ans, r[i + 1] - l[i] - 1); 36 | } 37 | ans = max(ans, m - l[n - 1] - 1); 38 | return ans; 39 | } 40 | 41 | -------------------------------------------------------------------------------- /InterviewBit/RemoveTrees.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Remove trees 3 | 4 | Given N trees in a line with ith tree having height h[i]. 5 | 6 | You have to remove all the trees except the first one and the last one. 7 | 8 | The cost of removing ith tree is height[i - 1] * height[i] * height[i + 1]. 9 | 10 | As soon as the tree is removed it will not exist in the line anymore. 11 | 12 | You have to remove the trees in such a way that minimizes the cost. 13 | 14 | Constraints: 15 | 16 | 2 <= N <= 19 17 | 0 <= h[i] <= 400 18 | 19 | Input: 20 | 21 | An array of length N denoting height of trees. 22 | 23 | Output: 24 | 25 | Integer denoting minimum cost. 26 | 27 | Example: 28 | 29 | Input: 30 | [1 2 4 3] 31 | 32 | Output: 33 | 20 34 | 35 | Explanation: 36 | Remove tree having height 2 first and then 4. So, total cost is (1 * 2 * 4) + (1 * 4 * 3) = 8 + 12 = 20. 37 | 38 | × 39 | --> 40 | */ 41 | 42 | int dp[20][20]; 43 | 44 | int minCost(vector& A, int l, int r) { 45 | if(r - l <= 1) { 46 | return 0; 47 | } 48 | if(dp[l][r] != -1) 49 | return dp[l][r]; 50 | int ans = INT_MAX; 51 | for(int k = l + 1; k < r; k++) { 52 | ans = min(ans, A[l] * A[k] * A[r] + minCost(A, l, k) + minCost(A, k, r)); 53 | } 54 | return dp[l][r] = ans; 55 | } 56 | 57 | int Solution::solve(vector &A) { 58 | memset(dp, -1, sizeof dp); 59 | return minCost(A, 0, A.size() - 1); 60 | } 61 | 62 | -------------------------------------------------------------------------------- /InterviewBit/RepeatingSubSequence.cpp: -------------------------------------------------------------------------------- 1 | int Solution::anytwo(string A) { 2 | int n = A.size(); 3 | int dp[n + 1][n + 1]; 4 | memset(dp, 0, sizeof dp); 5 | for(int i = 1; i <= n; i++) { 6 | for(int j = 1; j <= n; j++) { 7 | if(A[i - 1] == A[j - 1] && i != j) { 8 | dp[i][j] = 1 + dp[i - 1][j - 1]; 9 | } 10 | else { 11 | dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]); 12 | } 13 | } 14 | } 15 | return (dp[n][n] > 1); 16 | } 17 | 18 | -------------------------------------------------------------------------------- /InterviewBit/RodCutting.cpp: -------------------------------------------------------------------------------- 1 | long f(int i, int j, vector& cuts, vector>& dp, 2 | vector>& parent) { 3 | if(j - i == 1) 4 | return 0; 5 | if(dp[i][j] != -1) 6 | return dp[i][j]; 7 | long ans = LLONG_MAX, idx = -1; 8 | for(int k = i + 1; k < j; k++) { 9 | long curr = cuts[j] - cuts[i] + f(i, k, cuts, dp, parent) + 10 | f(k, j, cuts, dp, parent); 11 | if(curr < ans) { 12 | ans = curr; 13 | idx = k; 14 | } 15 | } 16 | parent[i][j] = idx; 17 | return dp[i][j] = ans; 18 | } 19 | 20 | void rec(vector& B, vector& ret, vector>& parent, int i, int j) { 21 | if(j - i == 1) 22 | return; 23 | int idx = parent[i][j]; 24 | ret.push_back(B[idx]); 25 | rec(B, ret, parent, i, idx); rec(B, ret, parent, idx, j); 26 | } 27 | 28 | vector Solution::rodCut(int A, vector &B) { 29 | sort(B.begin(), B.end()); 30 | B.insert(B.begin(), 0); 31 | B.push_back(A); 32 | vector ret; 33 | vector> dp(B.size(), vector(B.size(), -1)); 34 | vector> parent(B.size(), vector(B.size(), -1)); 35 | f(0, B.size() - 1, B, dp, parent); 36 | rec(B, ret, parent, 0, B.size() - 1); 37 | return ret; 38 | } 39 | -------------------------------------------------------------------------------- /InterviewBit/ScrambleString.cpp: -------------------------------------------------------------------------------- 1 | bool isScrambleUtil(const string A, const string B, unordered_map& mp) { 3 | if(A == B) 4 | return 1; 5 | if(mp.count(A + B)) 6 | return mp[A + B]; 7 | int cnt[26] = {0}; 8 | for(int i = 0; i < A.size(); i++) { 9 | cnt[A[i] - 'a']++; 10 | cnt[B[i] - 'a']--; 11 | } 12 | for(int i = 0; i < 26; i++) { 13 | if(cnt[i]) 14 | return false; 15 | } 16 | bool res = false; 17 | for(int i = 1; i < A.size(); i++) { 18 | res = res || (isScrambleUtil(A.substr(0, i), B.substr(0, i), mp) && 19 | isScrambleUtil(A.substr(i), B.substr(i), mp)) || 20 | (isScrambleUtil(A.substr(0, i), B.substr(A.size() - i), mp) && 21 | isScrambleUtil(A.substr(i), B.substr(0, A.size() - i), mp)); 22 | } 23 | return mp[A + B] = res; 24 | } 25 | 26 | int Solution::isScramble(const string A, const string B) { 27 | unordered_map mp; 28 | return isScrambleUtil(A, B, mp); 29 | } 30 | 31 | -------------------------------------------------------------------------------- /InterviewBit/SmallestSequenceWithGivenPrimes.cpp: -------------------------------------------------------------------------------- 1 | vector Solution::solve(int A, int B, int C, int D) { 2 | int ia, ib, ic, nexta = A, nextb = B, nextc = C; 3 | ia = ib = ic = 0; 4 | vector ret; 5 | for(int i = 0; i < D; i++) { 6 | ret.push_back(min(nexta, min(nextb, nextc))); 7 | if(ret[i] == nexta) 8 | nexta = ret[ia++] * A; 9 | if(ret[i] == nextb) 10 | nextb = ret[ib++] * B; 11 | if(ret[i] == nextc) 12 | nextc = ret[ic++] * C; 13 | } 14 | return ret; 15 | } 16 | 17 | -------------------------------------------------------------------------------- /InterviewBit/Submatrices WIth Sum Zero.cpp: -------------------------------------------------------------------------------- 1 | int Solution::solve(vector > &A) { 2 | int K = 0; 3 | int cnt = 0; 4 | for(int i = 0; i < A.size(); i++) { 5 | unordered_map mp; 6 | vector sum(A[0].size(), 0); 7 | int t = 0; 8 | mp[0]++; 9 | for(int j = i + 1; j < A.size(); j++) { 10 | for(int k = 0; k < A[0].size(); k++) { 11 | sum[k] += A[j][k]; 12 | t += sum[k]; 13 | cnt += mp[t - K]; 14 | mp[t]++; 15 | } 16 | } 17 | } 18 | return cnt; 19 | } 20 | 21 | -------------------------------------------------------------------------------- /InterviewBit/Tushar's Birthday Bombs.cpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | vector Solution::solve(int A, vector &B) { 4 | int mn = INT_MAX, pos = -1, n = B.size(); 5 | for(int i = 0; i < n; i++) { 6 | if(B[i] < mn) { 7 | mn = B[i]; 8 | pos = i; 9 | } 10 | } 11 | int maxKick = A / mn; 12 | vector ret; 13 | for(int i = 0; i < maxKick; i++) 14 | ret.push_back(pos); 15 | int rem = A - (maxKick * mn); 16 | int i = 0, j = 0; 17 | while(i < maxKick) { 18 | pos = ret[i]; 19 | int idx = -1; 20 | for(j = 0; j < n; j++) { 21 | if(rem - B[j] + B[pos] >= 0) { 22 | rem = rem - B[j] + B[pos]; 23 | break; 24 | } 25 | } 26 | if(j == n) 27 | break; 28 | ret[i] = j; 29 | i++; 30 | } 31 | return ret; 32 | } 33 | 34 | 35 | -------------------------------------------------------------------------------- /InterviewBit/Tushar'sBirthdayParty.cpp: -------------------------------------------------------------------------------- 1 | int Solution::solve(const vector &A, const vector &cap, const vector &cost) { 2 | int mx = INT_MIN; 3 | for(int i = 0; i < A.size(); i++) 4 | mx = max(mx, A[i]); 5 | int n = cost.size(); 6 | vector> dp(n + 1, vector(mx + 1)); 7 | for(int i = 0; i <= n; i++) { 8 | for(int j = 0; j <= mx; j++) { 9 | if(j == 0) { 10 | dp[i][j] = 0; 11 | } 12 | else if(i == 0) { 13 | dp[i][j] = 1e6; 14 | } 15 | else { 16 | if(cap[i - 1] <= j) { 17 | dp[i][j] = min(dp[i - 1][j], cost[i - 1] + dp[i][j - cap[i - 1]]); 18 | } 19 | else { 20 | dp[i][j] = dp[i - 1][j]; 21 | } 22 | } 23 | } 24 | } 25 | int ret = 0; 26 | for(int i = 0; i < A.size(); i++) { 27 | ret += dp[n][A[i]]; 28 | } 29 | return ret; 30 | } 31 | 32 | -------------------------------------------------------------------------------- /InterviewBit/TwoStrings.cpp: -------------------------------------------------------------------------------- 1 | int vis[100001]; 2 | 3 | int twoStrings(string s, int i, string t, int j) { 4 | if(j == t.size()) 5 | return 1; 6 | if(i == s.size()) 7 | return 0; 8 | if(s[i] == t[j]) { 9 | if(twoStrings(s, i + 1, t, j + 1)) { 10 | vis[i] = 1; 11 | } 12 | twoStrings(s, i + 1, t, j + 1); 13 | twoStrings(s, i + 1, t, j); 14 | } 15 | else 16 | return twoStrings(s, i + 1, t, j); 17 | } 18 | 19 | int Solution::solve(string A, string B) { 20 | memset(vis, 0, sizeof vis); 21 | twoStrings(A, 0, B, 0); 22 | for(int i = 0; i < A.size(); i++) { 23 | if(!vis[i]) 24 | return 0; 25 | } 26 | return 1; 27 | } 28 | -------------------------------------------------------------------------------- /InterviewBit/UniquePathsInAGrid.cpp: -------------------------------------------------------------------------------- 1 | int paths(vector>& A, int r, int c, int n, int m, 2 | vector>& dp) { 3 | if(r == n - 1 && c == m - 1 && A[r][c] == 0) 4 | return 1; 5 | if(r >= n || c >= m || A[r][c] == 1) 6 | return 0; 7 | if(dp[r][c] != -1) 8 | return dp[r][c]; 9 | int option1 = paths(A, r + 1, c, n, m, dp); 10 | int option2 = paths(A, r, c + 1, n, m, dp); 11 | int ans; 12 | ans = option1 + option2; 13 | return dp[r][c] = ans; 14 | } 15 | 16 | int Solution::uniquePathsWithObstacles(vector> &A) { 17 | int n = A.size(), m = A[0].size(); 18 | vector> dp(n + 1, vector(m + 1, -1)); 19 | return paths(A, 0, 0, n, m, dp); 20 | } 21 | 22 | -------------------------------------------------------------------------------- /InterviewBit/Ways To Color A 3XN Board.cpp: -------------------------------------------------------------------------------- 1 | #define MOD 1000000007 2 | #define ll long long int 3 | 4 | ll dp[150001][4][4][4]; 5 | 6 | struct triplet { 7 | int x, y, z; 8 | }; 9 | 10 | ll f(int i, int j, int k, int n, vector& trip) { 11 | if(n == 0) 12 | return 1; 13 | if(dp[n][i][j][k] != -1) 14 | return dp[n][i][j][k]; 15 | ll ans = 0; 16 | for(int a = 0; a < trip.size(); a++) { 17 | if(trip[a].x != i && trip[a].y != j && trip[a].z != k) { 18 | ans = (ans % MOD + f(trip[a].x, trip[a].y, trip[a].z, n - 1, trip) % MOD) % MOD; 19 | } 20 | } 21 | return dp[n][i][j][k] = ans % MOD; 22 | } 23 | 24 | int Solution::solve(int A) { 25 | memset(dp, -1, sizeof dp); 26 | vector trip; 27 | for(int i = 0; i < 4; i++) { 28 | for(int j = 0; j < 4; j++) { 29 | for(int k = 0; k < 4; k++) { 30 | if(i != j && j != k) { 31 | trip.push_back({ i, j, k }); 32 | } 33 | } 34 | } 35 | } 36 | ll ret = 0; 37 | for(int i = 0; i < trip.size(); i++) { 38 | ret = (ret % MOD + f(trip[i].x, trip[i].y, trip[i].z, A - 1, trip) % MOD) % MOD; 39 | } 40 | return (int)ret; 41 | } 42 | -------------------------------------------------------------------------------- /InterviewBit/Ways To Decode.cpp: -------------------------------------------------------------------------------- 1 | int dp[100001]; 2 | 3 | int f(string s, int i) { 4 | if(i == s.size()) 5 | return 1; 6 | if(dp[i] != -1) 7 | return dp[i]; 8 | int ans = 0; 9 | if(s[i] >= '1' && s[i] <= '9') 10 | ans += f(s, i + 1); 11 | if(i < s.size() - 1) { 12 | string sub = s.substr(i, 2); 13 | if(sub >= "10" && sub <= "26") { 14 | ans += f(s, i + 2); 15 | } 16 | } 17 | return ans; 18 | } 19 | 20 | int Solution::numDecodings(string A) { 21 | memset(dp, -1, sizeof dp); 22 | return f(A, 0); 23 | } 24 | 25 | -------------------------------------------------------------------------------- /InterviewBit/WordBreak.cpp: -------------------------------------------------------------------------------- 1 | bool f(string s, unordered_set& st, int i, vector& dp) { 2 | if(i == s.size()) 3 | return true; 4 | if(dp[i] != -1) 5 | return dp[i]; 6 | bool ans = false; 7 | for(int j = i; j < s.size(); j++) { 8 | if(st.find(s.substr(i, j - i + 1)) != st.end()) { 9 | ans |= f(s, st, j + 1, dp); 10 | } 11 | } 12 | return dp[i] = ans; 13 | } 14 | 15 | int Solution::wordBreak(string A, vector &B) { 16 | vector dp(A.size() + 1, 0); 17 | unordered_set st; 18 | for(string s : B) 19 | st.insert(s); 20 | for(int i = A.size() - 1; i >= 0; i--) { 21 | for(int j = i; j < A.size(); j++) { 22 | string curr = A.substr(i, j - i + 1); 23 | if(st.find(curr) != st.end() && dp[j + 1] == 1) { 24 | dp[i] = 1; 25 | break; 26 | } 27 | } 28 | } 29 | return dp[0]; 30 | // return f(A, st, 0, dp); 31 | } 32 | 33 | -------------------------------------------------------------------------------- /LeetCode/1-bit And 2-bit Characters.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int dp[1001]; 4 | bool f(vector& bits, int i) { 5 | if(i < 0) 6 | return true; 7 | if(dp[i] != -1) 8 | return dp[i]; 9 | bool op1 = false, op2 = false; 10 | if(i >= 1) { 11 | if(bits[i] == 1 && bits[i - 1] == 1) 12 | return f(bits, i - 2); 13 | if(bits[i] == 0 && bits[i - 1] == 1) 14 | op1 = f(bits, i - 2); 15 | } 16 | if(bits[i] == 0) 17 | op2 = f(bits, i - 1); 18 | return dp[i] = op1 | op2; 19 | } 20 | 21 | bool isOneBitCharacter(vector& bits) { 22 | if(bits.back() == 1) 23 | return false; 24 | memset(dp, -1, sizeof dp); 25 | return f(bits, bits.size() - 2); 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /LeetCode/120_recursion.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | const int maxVal = 1e7; 4 | 5 | int minPathSum(vector>& triangle, vector>& dp, int i, int j) { 6 | if (i >= triangle.size() || j >= triangle[i].size()) { 7 | return maxVal; 8 | } 9 | if (dp[i][j] != maxVal) { 10 | return dp[i][j]; 11 | } 12 | if (i == triangle.size() - 1) { 13 | return triangle[i][j]; 14 | } 15 | return dp[i][j] = triangle[i][j] + min( 16 | minPathSum(triangle, dp, i + 1, j), minPathSum(triangle, dp, i + 1, j + 1)); 17 | } 18 | 19 | int minimumTotal(vector>& triangle) { 20 | int n = triangle.size(); 21 | vector> dp(n, vector(n, maxVal)); 22 | return minPathSum(triangle, dp, 0, 0); 23 | } 24 | }; 25 | -------------------------------------------------------------------------------- /LeetCode/120_space_optimized.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int minimumTotal(vector>& triangle) { 4 | int n = triangle.size(); 5 | vector currRow(n, 0); 6 | vector nextRow(triangle[n - 1]); 7 | for (int i = n - 2; i >= 0; i--) { 8 | for (int j = 0; j < i + 1; j++) { 9 | currRow[j] = triangle[i][j] + min(nextRow[j], nextRow[j + 1]); 10 | } 11 | swap(currRow, nextRow); 12 | } 13 | return nextRow[0]; 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /LeetCode/139.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | unordered_map wordPresent; 4 | int wordBreakRec(string s, vector& wordDict, vector& dp, int start) { 5 | if (start >= s.size()) { 6 | return start == s.size(); 7 | } 8 | if (dp[start] != -1) { 9 | return dp[start]; 10 | } 11 | string temp = ""; 12 | bool ans = false; 13 | for (int i = start; i < s.size(); i++) { 14 | temp += s[i]; 15 | if (wordPresent[temp]) { 16 | ans |= wordBreakRec(s, wordDict, dp, i + 1); 17 | } 18 | } 19 | return dp[start] = ans ? 1 : 0; 20 | } 21 | 22 | bool wordBreak(string s, vector& wordDict) { 23 | int n = s.size(); 24 | // vector dp(n + 1, -1); 25 | for (int i = 0; i < wordDict.size(); i++) { 26 | wordPresent[wordDict[i]] = true; 27 | } 28 | vector dp(n + 1, false); 29 | dp[n] = true; 30 | string temp; 31 | for (int j = n - 1; j >= 0; j--) { 32 | temp = ""; 33 | for (int i = j; i >= 0; i--) { 34 | temp = s[i] + temp; 35 | if (wordPresent[temp] && dp[j + 1]) { 36 | dp[i] = true; 37 | } 38 | } 39 | } 40 | return dp[0]; 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /LeetCode/2 Keys Keyboard.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int N; 4 | int dp[1001][1001]; 5 | int f(int n, int selected) { 6 | if(n == N) { 7 | return 0; 8 | } 9 | if(n > N) { 10 | return 1e7; 11 | } 12 | if(dp[n][selected] != -1) 13 | return dp[n][selected]; 14 | int copy = 1e7, paste = 1e7; 15 | if(selected) 16 | paste = 1 + f(n + selected, selected); 17 | copy = 2 + f(n + n, n); 18 | return min(copy, paste); 19 | } 20 | 21 | int minSteps(int n) { 22 | memset(dp, -1, sizeof dp); 23 | N = n; 24 | return f(1, 0); 25 | } 26 | }; 27 | -------------------------------------------------------------------------------- /LeetCode/2369.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool helper(vector& nums, vector& dp, int i) { 4 | int n = nums.size(); 5 | if (i >= n) { 6 | return true; 7 | } 8 | if (dp[i] != -1) { 9 | return (dp[i] == 1); 10 | } 11 | bool ans = false; 12 | if (i < n - 1 && nums[i] == nums[i + 1]) { 13 | ans |= helper(nums, dp, i + 2); 14 | if (i < n - 2 && nums[i] == nums[i + 2]) { 15 | ans |= helper(nums, dp, i + 3); 16 | } 17 | } 18 | if (i < n - 2 && nums[i + 2] == nums[i + 1] + 1 && nums[i + 1] == nums[i] + 1) { 19 | ans |= helper(nums, dp, i + 3); 20 | } 21 | dp[i] = (int)ans; 22 | return ans; 23 | } 24 | 25 | bool validPartition(vector& nums) { 26 | int n = nums.size(); 27 | vector dp(n, -1); 28 | return helper(nums, dp, 0); 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /LeetCode/322.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | const int MAX_VAL = 1e9; 4 | int coinChangeRec(vector& coins, vector& dp, int amount) { 5 | if (amount == 0) { 6 | return 0; 7 | } 8 | if (amount < 0) { 9 | return MAX_VAL; 10 | } 11 | if (dp[amount] != MAX_VAL) { 12 | return dp[amount]; 13 | } 14 | int minCoins = INT_MAX; 15 | for (int i = 0; i < coins.size(); i++) { 16 | int coinsUsed = 1 + coinChangeRec(coins, dp, amount - coins[i]); 17 | minCoins = min(minCoins, coinsUsed); 18 | } 19 | return dp[amount] = minCoins; 20 | } 21 | 22 | int coinChange(vector& coins, int amount) { 23 | vector dp(1e4 + 1, MAX_VAL); 24 | dp[0] = 0; 25 | for (int i = 1; i <= amount; i++) { 26 | for (int j = 0; j < coins.size(); j++) { 27 | if (i >= coins[j]) { 28 | dp[i] = min(dp[i], 1 + dp[i - coins[j]]); 29 | } 30 | } 31 | } 32 | // int res = coinChangeRec(coins, dp, amount); 33 | // if (res >= MAX_VAL) { 34 | // res = -1; 35 | // } 36 | return dp[amount] == MAX_VAL ? -1 : dp[amount]; 37 | } 38 | }; 39 | -------------------------------------------------------------------------------- /LeetCode/329.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int longestPath(vector>& A, vector>& dp, int i, int j) { 4 | if (i < 0 || j < 0 || i >= A.size() || j >= A[0].size()) 5 | return 0; 6 | if (dp[i][j] != -1) 7 | return dp[i][j]; 8 | 9 | vector> v = { { -1, 0 }, { 0, -1 }, { 0, 1 },{ 1, 0 } }; 10 | int ans = 1; 11 | for (int k = 0; k < 4; k++) { 12 | int ci = i + v[k][0], cj = j + v[k][1]; 13 | if ( 14 | ci >= 0 && ci <= A.size() - 1 15 | && cj >= 0 && cj <= A[0].size() - 1 && A[i][j] < A[ci][cj] 16 | ) { 17 | ans = max(ans, 1 + longestPath(A, dp, ci, cj)); 18 | } 19 | } 20 | return dp[i][j] = ans; 21 | } 22 | 23 | int longestIncreasingPath(vector>& A) { 24 | int ans = 0; 25 | int n = A.size(), m = A[0].size(); 26 | vector> dp(n, vector(m, -1)); 27 | for (int i = 0; i < n; i++) { 28 | for(int j = 0; j < m; j++) { 29 | ans = max(ans, longestPath(A, dp, i, j)); 30 | } 31 | } 32 | return ans; 33 | } 34 | }; 35 | -------------------------------------------------------------------------------- /LeetCode/91.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | private: 3 | int dp[101]; 4 | int decodeWays(string s, int i) { 5 | if (i == s.size()) { 6 | return 1; 7 | } 8 | if (dp[i] != -1) { 9 | return dp[i]; 10 | } 11 | int total = 0; 12 | if (s[i] >= '1' && s[i] <= '9') { 13 | total += decodeWays(s, i + 1); 14 | } 15 | if (i < s.size() - 1) { 16 | int num = ((s[i] - '0') * 10) + (s[i + 1] - '0'); 17 | if (num <= 26 && num >= 10) { 18 | total += decodeWays(s, i + 2); 19 | } 20 | } 21 | return dp[i] = total; 22 | } 23 | public: 24 | int numDecodings(string s) { 25 | memset(dp, -1, sizeof dp); 26 | return decodeWays(s, 0); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /LeetCode/Airplane Seat Assignment Probability.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | double nthPersonGetsNthSeat(int n) { 4 | vector dp(n); 5 | dp[0] = 1.0; 6 | for(int i = 1; i < n; i++) { 7 | dp[i] = (1.0 / (i + 1)) + (0.0 / (i + 1)) + (dp[i - 1] * (i - 1) / (i + 1)); 8 | } 9 | return dp[n - 1]; 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /LeetCode/Arithmetic Slices II.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int numberOfArithmeticSlices(vector& A) { 4 | vector> dp(A.size()); 5 | int ans = 0, n = A.size(); 6 | for(int j = 1; j < n; j++) { 7 | for(int i = 0; i < j; i++) { 8 | long diff = (long)A[j] - (long)A[i]; 9 | dp[j][diff] += (1 + dp[i][diff]); 10 | ans += dp[i][diff]; 11 | } 12 | } 13 | return ans; 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /LeetCode/Array Nesting.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int dfs(vector& nums, vector& ans, int i, int j) { 4 | if(i == j) 5 | return 1; 6 | if(ans[j] > 1) 7 | return ans[j]; 8 | ans[j] = 1 + dfs(nums, ans, i, nums[j]); 9 | return ans[j]; 10 | } 11 | 12 | int arrayNesting(vector& nums) { 13 | int n = nums.size(), mx = 0; 14 | vector ans(n, 1); 15 | for(int i = 0; i < nums.size(); i++) { 16 | if(ans[i] == 1) 17 | ans[i] = dfs(nums, ans, i, nums[i]); 18 | mx = max(mx, ans[i]); 19 | } 20 | return mx; 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /LeetCode/Beautiful Arrangement.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | map>, int> mp; 4 | int dfs(int N, int i, vector& vis) { 5 | if(i > N) 6 | return 1; 7 | int ans = 0; 8 | if(mp.count({ i , vis })) 9 | return mp[{ i, vis }]; 10 | for(int num = 1; num <= N; num++) { 11 | if(vis[num]) 12 | continue; 13 | if(num % i == 0 || i % num == 0) { 14 | vis[num] = true; 15 | ans += dfs(N, i + 1, vis); 16 | vis[num] = false; 17 | } 18 | } 19 | return mp[{ i, vis }] = ans; 20 | } 21 | 22 | int countArrangement(int N) { 23 | if(N <= 0) 24 | return 0; 25 | vector vis(N, false); 26 | return dfs(N, 1, vis); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /LeetCode/Best Time To Buy And Sell Stock With Transaction Fee.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int dp[50000][2]; 4 | int tFee; 5 | int f(vector& prices, int i, bool buy) { 6 | if(i == prices.size()) 7 | return (buy ? 0 : -1e4); 8 | if(dp[i][buy] != -1) 9 | return dp[i][buy]; 10 | int op1 = 0, op2 = 0; 11 | if(buy) { 12 | op1 = -prices[i] + f(prices, i + 1, 0); 13 | op2 = f(prices, i + 1, 1); 14 | } 15 | else { 16 | op1 = prices[i] - tFee + f(prices, i + 1, 1); 17 | op2 = f(prices, i + 1, 0); 18 | } 19 | return dp[i][buy] = max(op1, op2); 20 | } 21 | 22 | int maxProfit(vector& prices, int fee) { 23 | tFee = fee; 24 | memset(dp, -1, sizeof dp); 25 | return f(prices, 0, 1); 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /LeetCode/BestTimeToBuyAndSellStockIII.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int maxProfit(vector& prices) { 4 | int oneBuy = INT_MIN, oneBuyOneSell = 0, twoBuy = INT_MIN, 5 | twoBuyTwoSell = 0; 6 | for(int i = 0; i < prices.size(); i++) { 7 | twoBuyTwoSell = max(twoBuyTwoSell, prices[i] + twoBuy); 8 | twoBuy = max(twoBuy, oneBuyOneSell - prices[i]); 9 | oneBuyOneSell = max(oneBuyOneSell, prices[i] + oneBuy); 10 | oneBuy = max(oneBuy, -prices[i]); 11 | } 12 | return twoBuyTwoSell; 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /LeetCode/BestTimeToBuyAndSellStockIV.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int maxPro(int k, int i, vector& prices, vector>& dp) { 4 | if(k == 0) 5 | return 0; 6 | if(i == prices.size()) { 7 | return 0; 8 | } 9 | if(dp[i][k] != -1) 10 | return dp[i][k]; 11 | int option1, option2, option3; 12 | option2 = 0; 13 | option1 = maxPro(k, i + 1, prices, dp); 14 | if(k % 2 == 0) { 15 | option2 = -prices[i] + maxPro(k - 1, i + 1, prices, dp); 16 | } 17 | else { 18 | option2 = prices[i] + maxPro(k - 1, i + 1, prices, dp); 19 | } 20 | return dp[i][k] = max(option1, option2); 21 | } 22 | 23 | int maxProfit(int k, vector& prices) { 24 | vector> dp(prices.size() + 1, vector(2 * k + 1, -1)); 25 | // memset(dp, -1, sizeof dp); 26 | return maxPro(2 * k, 0, prices, dp); 27 | } 28 | }; 29 | 30 | /* 31 | class Solution { 32 | public: 33 | int maxProfit(int k, vector &prices) { 34 | int N = prices.size(); 35 | if (k == 0 || N < 2) return 0; 36 | 37 | if (k > N / 2) { 38 | int sum = 0; 39 | for (int i = 1; i < N; i++){ 40 | if (prices[i] > prices[i - 1]){ 41 | sum += prices[i] - prices[i - 1]; 42 | } 43 | } 44 | return sum; 45 | } 46 | 47 | vector buy(k + 1, INT_MIN); 48 | vector sell(k + 1, 0); 49 | for (int i = 0; i< N; ++i) { 50 | for (int j = 1; j <= k; ++j) { 51 | buy[j] = max(buy[j], sell[j - 1] - prices[i]); 52 | sell[j] = max(sell[j], buy[j] + prices[i]); 53 | } 54 | } 55 | return sell[k]; 56 | } 57 | }; 58 | */ 59 | -------------------------------------------------------------------------------- /LeetCode/Binary Trees With Factors.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int numFactoredBinaryTrees(vector& A) { 4 | int n = A.size(); 5 | long mod = 1e9 + 7, ans = 0; 6 | sort(A.begin(), A.end()); 7 | unordered_map dp; 8 | for(int i = 0; i < A.size(); i++) { 9 | dp[A[i]] = 1; 10 | for(int j = 0; j < i; j++) { 11 | if(A[i] % A[j] == 0) 12 | dp[A[i]] = (dp[A[i]] + dp[A[j]] * dp[A[i] / A[j]]) % mod; 13 | } 14 | ans+= dp[A[i]]; 15 | ans %= mod; 16 | } 17 | return (int)ans; 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /LeetCode/Bitmasking/SmallestSufficientTeam.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | map skill; 4 | vector res[(1 << 16) + 5]; 5 | int dp[(1 << 16) + 5]; 6 | int person[65]; 7 | 8 | vector smallestSufficientTeam(vector& req_skills, vector>& people) { 9 | for(int i = 0; i < req_skills.size(); i++) { 10 | skill[req_skills[i]] = i; 11 | } 12 | for(int i = 0; i < people.size(); i++) { 13 | person[i] = 0; 14 | for(int j = 0; j < people[i].size(); j++) { 15 | person[i] |= (1 << skill[people[i][j]]); 16 | } 17 | } 18 | memset(dp, -1, sizeof dp); 19 | dp[0] = 0; 20 | for(int i = 0; i < (1 << req_skills.size()); i++) { 21 | if(dp[i] == -1) 22 | continue; 23 | for(int j = 0; j < people.size(); j++) { 24 | if(dp[i | person[j]] == -1 || dp[i | person[j]] > dp[i] + 1) { 25 | dp[i | person[j]] = dp[i] + 1; 26 | res[i | person[j]] = res[i]; 27 | res[i | person[j]].push_back(j); 28 | } 29 | } 30 | } 31 | return res[(1 << req_skills.size()) - 1]; 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /LeetCode/Build Array Where You Can Find The Maximum Exactly K Comparisons.cpp: -------------------------------------------------------------------------------- 1 | #define ll long long int 2 | 3 | class Solution { 4 | public: 5 | int dp[51][101][51]; 6 | ll MOD; 7 | int f(int n, int mx, int m, int k) { 8 | if(n == 0) { 9 | return k == 0; 10 | } 11 | if(k < 0) 12 | return 0; 13 | if(dp[n][mx][k] != -1) 14 | return dp[n][mx][k]; 15 | ll ans = 0; 16 | for(int j = 1; j <= mx; j++) { 17 | ans = (ans + f(n - 1, mx, m, k)) % MOD; 18 | } 19 | for(int j = mx + 1; j <= m; j++) { 20 | ans = (ans + f(n - 1, j, m, k - 1)) % MOD; 21 | } 22 | return dp[n][mx][k] = (int)ans; 23 | } 24 | 25 | int numOfArrays(int n, int m, int k) { 26 | ll ans = 0; 27 | if(m < k) 28 | return 0; 29 | MOD = 1e9 + 7; 30 | memset(dp, -1, sizeof dp); 31 | for(int i = 1; i <= m; i++) 32 | ans = (ans + f(n - 1, i, m, k - 1)) % MOD; 33 | return (int)ans; 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /LeetCode/BurstBallons.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | private: 3 | int dp[501][501]; 4 | public: 5 | int f(vector& nums, int l, int r) { 6 | if(l == r) 7 | return nums[l - 1] * nums[l] * nums[l + 1]; 8 | if(dp[l][r] != -1) 9 | return dp[l][r]; 10 | int ans = 0; 11 | for(int i = l; i <= r; i++) { 12 | ans = max(ans, f(nums, l, i - 1) + f(nums, i + 1, r) + nums[l - 1] * nums[i] * nums[r + 1]); 13 | } 14 | return dp[l][r] = ans; 15 | } 16 | 17 | int maxCoins(vector& nums) { 18 | memset(dp, -1, sizeof dp); 19 | nums.insert(nums.begin(), 1); 20 | nums.push_back(1); 21 | return f(nums, 1, nums.size() - 2); 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /LeetCode/Can I Win.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int dp[1 << 20]; 4 | int dfs(int mask, int mx, int total) { 5 | if(total <= 0) 6 | return false; 7 | if(dp[mask] != -1) 8 | return dp[mask]; 9 | for(int i = 0; i < mx; i++) { 10 | if((mask & (1 << i)) == 0) { 11 | if(!dfs(mask | (1 << i), mx, total - i - 1)) 12 | return dp[mask] = true; 13 | } 14 | } 15 | return dp[mask] = false; 16 | } 17 | 18 | bool canIWin(int mx, int total) { 19 | memset(dp, -1, sizeof dp); 20 | if(total == 0) 21 | return true; 22 | int maxSum = mx * (mx + 1) / 2; 23 | if(maxSum < total) 24 | return false; 25 | return dfs(0, mx, total); 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /LeetCode/Champagne Tower.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | double champagneTower(int poured, int query_row, int query_glass) { 4 | double ret[101][101] = { 0.0 }; 5 | ret[0][0] = poured; 6 | for(int i = 0; i < 100; i++) { 7 | for(int j = 0; j <= i; j++) { 8 | if(ret[i][j] >= 1) { 9 | ret[i + 1][j] += (ret[i][j] - 1) / 2.0; 10 | ret[i + 1][j + 1] += (ret[i][j] - 1) / 2.0; 11 | ret[i][j] = 1; 12 | } 13 | } 14 | } 15 | return ret[query_row][query_glass]; 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /LeetCode/Cherry Pickup.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int dp[51][51][51]; 4 | int f(vector>& g, int r1, int c1, int r2, int c2) { 5 | if(r1 >= g.size() || r2 >= g.size() || c1 >= g.size() || c2 >= g.size() || g[r1][c1] == -1 || g[r2][c2] == -1) 6 | return -1e5; 7 | if(r1 == g.size() - 1 && c1 == g.size() - 1) 8 | return g[r1][c1]; 9 | if(r2 == g.size() - 1 && c2 == g.size() - 1) 10 | return g[r2][c2]; 11 | if(dp[r1][c1][c2] != -1) 12 | return dp[r1][c1][c2]; 13 | int cherries = 0; 14 | if(r1 == r2 && c1 == c2) { 15 | cherries = g[r1][c1]; 16 | } 17 | else { 18 | cherries = g[r1][c1] + g[r2][c2]; 19 | } 20 | int ans = f(g, r1 + 1, c1, r2 + 1, c2); 21 | ans = max(ans, f(g, r1 + 1, c1, r2, c2 + 1)); 22 | ans = max(ans, f(g, r1, c1 + 1, r2 + 1, c2)); 23 | ans = max(ans, f(g, r1, c1 + 1, r2, c2 + 1)); 24 | return dp[r1][c1][c2] = cherries + ans; 25 | } 26 | 27 | int cherryPickup(vector>& grid) { 28 | memset(dp, -1, sizeof dp); 29 | int ans = f(grid, 0, 0, 0, 0); 30 | return max(ans, 0); 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /LeetCode/Concatenated Words.cpp: -------------------------------------------------------------------------------- 1 | static bool cmp(string a, string b) { 2 | return a.size() < b.size(); 3 | } 4 | 5 | class Solution { 6 | public: 7 | 8 | unordered_set st; 9 | int f(string s) { 10 | if(!s.size() || st.find(s) != st.end()) { 11 | return true; 12 | } 13 | bool ans = false; 14 | string curr; 15 | for(int i = 0; i < s.size(); i++) { 16 | curr += s[i]; 17 | if(st.find(curr) != st.end()) { 18 | ans |= f(s.substr(i + 1)); 19 | } 20 | } 21 | return ans; 22 | } 23 | 24 | vector findAllConcatenatedWordsInADict(vector& words) { 25 | sort(words.begin(), words.end(), cmp); 26 | vector ret; 27 | for(int i = 0; i < words.size(); i++) { 28 | if(words[i].size() && f(words[i])) 29 | ret.push_back(words[i]); 30 | st.insert(words[i]); 31 | } 32 | return ret; 33 | } 34 | }; 35 | -------------------------------------------------------------------------------- /LeetCode/CorporateFlightBookings.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector corpFlightBookings(vector>& b, int n) { 4 | vector ret(n, 0); 5 | for(auto &v : b) { 6 | ret[v[0] - 1] += v[2]; 7 | if(v[1] < n) 8 | ret[v[1]] -= v[2]; 9 | } 10 | for(int i = 1; i < n; i++) 11 | ret[i] += ret[i - 1]; 12 | return ret; 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /LeetCode/Count Square Submatrices With All Ones.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int dp[301][301]; 4 | int dfs(vector>& A, int i, int j) { 5 | if(i < 0 || j < 0 || i >= A.size() || j >= A[0].size() || A[i][j] != 1) 6 | return 0; 7 | if(dp[i][j] != -1) 8 | return dp[i][j]; 9 | int ans = 1; 10 | int l = dfs(A, i, j + 1), r = dfs(A, i + 1, j), t = dfs(A, i + 1, j + 1); 11 | ans = 1 + min(l, min(r, t)); 12 | return dp[i][j] = ans; 13 | } 14 | 15 | int countSquares(vector>& A) { 16 | int ans = 0; 17 | int n = A.size(), m = A[0].size(); 18 | vector> vis(n, vector(m, 0)); 19 | memset(dp, -1, sizeof dp); 20 | for(int i = 0; i < A.size(); i++) { 21 | for(int j = 0; j < A[i].size(); j++) { 22 | if(A[i][j]) { 23 | int sz = dfs(A, i, j); 24 | ans += sz; 25 | } 26 | } 27 | } 28 | return ans; 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /LeetCode/Count Vowels Permutation.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | long MOD; 4 | long dp[20001][5]; 5 | // a 0 1, e 1 0 or 2, i 2 no 2, o 3 2 or 4, u 4 0 6 | long f(int n, int i) { 7 | if(n == 0) 8 | return 1; 9 | long ans = 0; 10 | if(dp[n][i] != -1) 11 | return dp[n][i]; 12 | if(i == 0) 13 | ans = f(n - 1, 1); 14 | if(i == 1) 15 | ans = f(n - 1, 0) + f(n - 1, 2); 16 | if(i == 2) 17 | ans = f(n - 1, 0) + f(n - 1, 1) + f(n - 1, 3) + f(n - 1, 4); 18 | if(i == 3) 19 | ans = f(n - 1, 2) + f(n - 1, 4); 20 | if(i == 4) 21 | ans = f(n - 1, 0); 22 | ans %= MOD; 23 | return dp[n][i] = ans; 24 | } 25 | 26 | int countVowelPermutation(int n) { 27 | long ans = 0; 28 | MOD = 1e9 + 7; 29 | memset(dp, -1, sizeof dp); 30 | for(int i = 0; i < 5; i++) { 31 | ans += f(n - 1, i); 32 | ans %= MOD; 33 | } 34 | return (int)ans; 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /LeetCode/Decode Ways.cpp: -------------------------------------------------------------------------------- 1 | #define ll long long int 2 | 3 | class Solution { 4 | public: 5 | int MOD = 1e9 + 7; 6 | vector dp; 7 | ll f(string &s, int i) { 8 | if(i == s.size()) 9 | return 1; 10 | if(dp[i] != -1) 11 | return dp[i]; 12 | ll ans = 0; 13 | if(s[i] >= '1' && s[i] <= '9') 14 | ans = (ans % MOD + f(s, i + 1) % MOD) % MOD; 15 | if(s[i] == '*') 16 | ans = (ans % MOD + (9 * f(s, i + 1)) % MOD) % MOD; 17 | if(i < s.size() - 1) { 18 | if((s[i] == '1' && s[i + 1] >= '0' && s[i + 1] <= '9') || (s[i] == '2' && s[i + 1] >= '0' && s[i + 1] <= '6')) { 19 | ans = (ans % MOD + f(s, i + 2) % MOD) % MOD; 20 | } 21 | else if(s[i] == '1' && s[i + 1] == '*') { 22 | ans = (ans % MOD + (9 * f(s, i + 2)) % MOD) % MOD; 23 | } 24 | else if(s[i] == '2' && s[i + 1] == '*') { 25 | ans = (ans % MOD + (6 * f(s, i + 2)) % MOD) % MOD; 26 | } 27 | else if(s[i] == '*' && s[i + 1] == '*') { 28 | ans = (ans % MOD + (15 * f(s, i + 2)) % MOD) % MOD; 29 | } 30 | else if(s[i] == '*' && s[i + 1] >= '0' && s[i + 1] <= '6') { 31 | ans = (ans % MOD + (2 * f(s, i + 2)) % MOD) % MOD; 32 | } 33 | else if(s[i] == '*' && s[i + 1] >= '7' && s[i + 1] <= '9') { 34 | ans = (ans % MOD + f(s, i + 2) % MOD) % MOD; 35 | } 36 | } 37 | return dp[i] = ans; 38 | } 39 | 40 | int numDecodings(string s) { 41 | dp.clear(); 42 | dp.resize(s.size(), -1); 43 | if (s.size() > 1000) { 44 | int idx = s.size() - 1000; 45 | while (idx >= 0) { 46 | f(s, idx); 47 | if (idx == 0) { 48 | idx = -1; 49 | } 50 | else { 51 | idx -= 1000; 52 | idx = std::max(idx, 0); 53 | } 54 | } 55 | } 56 | return f(s, 0); 57 | } 58 | }; 59 | -------------------------------------------------------------------------------- /LeetCode/Delete And Earn.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | // int dp[20001]; 4 | /*int maxPoints(vector& coins, int i) { 5 | if(i == coins.size()) 6 | return 0; 7 | if(dp[i] != -1) 8 | return dp[i]; 9 | int pos = i, earned = 0; 10 | while(pos < coins.size() && coins[pos] == coins[i]) { 11 | earned += coins[pos++]; 12 | } 13 | int skipped = maxPoints(coins, pos); 14 | while(pos < coins.size() && coins[pos] == coins[i] + 1) { 15 | pos++; 16 | } 17 | earned += maxPoints(coins, pos); 18 | return dp[i] = max(skipped, earned); 19 | } */ 20 | 21 | int deleteAndEarn(vector& nums) { 22 | // memset(dp, -1, sizeof dp); 23 | sort(nums.begin(), nums.end()); 24 | // return maxPoints(nums, 0); 25 | int prev2 = 0, prev = 0, curr = 0, i = 0; 26 | while(i < nums.size()) { 27 | int pos = i; 28 | curr = 0; 29 | while(i < nums.size() && nums[i] == nums[pos]) 30 | curr += nums[i++]; 31 | // we can add prev if diff > 1 32 | if(pos >= 1 && nums[i - 1] > nums[pos - 1] + 1) 33 | curr += prev; 34 | else 35 | curr = max(curr + prev2, prev); 36 | prev2 = prev; 37 | prev = curr; 38 | } 39 | return curr; 40 | } 41 | }; 42 | -------------------------------------------------------------------------------- /LeetCode/Delete Columns To Make Sorted III.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int minDeletionSize(vector& A) { 4 | int m = A.size(), n = A[0].size(), ret = n - 1, k; 5 | vector dp(n, 1); 6 | for(int j = 0; j < n; j++) { 7 | for(int i = 0; i < j; i++) { 8 | for(k = 0; k < m; ++k) { 9 | if(A[k][i] > A[k][j]) { 10 | break; 11 | } 12 | } 13 | if(k == m && dp[i] + 1 > dp[j]) { 14 | dp[j] = dp[i] + 1; 15 | } 16 | ret = min(ret, n - dp[j]); 17 | } 18 | } 19 | return ret; 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /LeetCode/Delete Operation For Two Strings.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int dp[501][501]; 4 | int minDist(string s, int i, string t, int j) { 5 | if(i == s.size() && j == t.size()) { 6 | return 0; 7 | } 8 | if(i == s.size()) { 9 | return t.size() - j; 10 | } 11 | if(j == t.size()) { 12 | return s.size() - i; 13 | } 14 | if(dp[i][j] != -1) 15 | return dp[i][j]; 16 | if(s[i] == t[j]) { 17 | return minDist(s, i + 1, t, j + 1); 18 | } 19 | int option1 = minDist(s, i + 1, t, j); 20 | int option2 = minDist(s, i, t, j + 1); 21 | return dp[i][j] = 1 + min(option1, option2); 22 | } 23 | 24 | int minDistance(string word1, string word2) { 25 | memset(dp, -1, sizeof dp); 26 | return minDist(word1, 0, word2, 0); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /LeetCode/Dice Roll Simulation.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int dp[5001][7][16]; 4 | long MOD; 5 | long f(int n, vector& rollMax, int curr, int len) { 6 | if(curr < 6 && len > rollMax[curr]) 7 | return 0; 8 | if(n == 0) 9 | return 1; 10 | if(dp[n][curr][len] != -1) 11 | return dp[n][curr][len]; 12 | long ans = 0; 13 | for(int i = 0; i < 6; i++) { 14 | if(curr == i) { 15 | ans += f(n - 1, rollMax, curr, len + 1); 16 | } 17 | else { 18 | ans += f(n - 1, rollMax, i, 1); 19 | } 20 | } 21 | return dp[n][curr][len] = ans % MOD; 22 | } 23 | 24 | int dieSimulator(int n, vector& rollMax) { 25 | memset(dp, -1, sizeof dp); 26 | MOD = 1e9 + 7; 27 | return (int)f(n, rollMax, 6, 0); 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /LeetCode/Different Ways To Add Parentheses.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector diffWaysToCompute(string input) { 4 | vector ret; 5 | for(int i = 0; i < input.size(); i++) { 6 | char ch = input[i]; 7 | if(ch == '+' || ch == '-' || ch == '*') { 8 | vector lefts = diffWaysToCompute(input.substr(0, i)), rights = diffWaysToCompute(input.substr(i + 1)); 9 | for(int l : lefts) { 10 | for(int r : rights) { 11 | if(ch == '+') 12 | ret.push_back(l + r); 13 | else if(ch == '-') 14 | ret.push_back(l - r); 15 | else 16 | ret.push_back(l * r); 17 | } 18 | } 19 | } 20 | } 21 | if(!ret.size()) 22 | ret.push_back(atoi(input.c_str())); 23 | return ret; 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /LeetCode/Distinct Subsequences II.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int distinctSubseqII(string s) { 4 | vector cnt(26, -1); 5 | int n = s.size(); 6 | vector dp(n + 1, 1); 7 | const int MOD = 1e9 + 7; 8 | for(int i = 1; i <= n; i++) { 9 | dp[i] = (2 * dp[i - 1]) % MOD; 10 | if(cnt[s[i - 1] - 'a'] > 0) 11 | dp[i] = (dp[i] - dp[cnt[s[i - 1] - 'a'] - 1] + MOD) % MOD; 12 | cnt[s[i - 1] - 'a'] = i; 13 | } 14 | return (dp[n] - 1) % MOD; 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /LeetCode/DistinctSubsequencesII.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int distinctSubseqII(string S) { 4 | int pos[26] = {}, dp[S.size() + 1] = { 1 }, mod = 1e9 + 7; 5 | for(int i = 1; i <= S.size(); i++) { 6 | auto idx = S[i - 1] - 'a'; 7 | if(pos[idx]) 8 | dp[i] = mod - dp[pos[idx] - 1]; 9 | dp[i] = (dp[i] + dp[i - 1] * 2 % mod) % mod; 10 | pos[S[i - 1] - 'a'] = i; 11 | } 12 | return dp[S.size()] - 1; 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /LeetCode/DivisorGame.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int dp[1001] = {}; 4 | bool divisorGame(int N, bool res = false) { 5 | // return (N % 2 == 0); 6 | if(dp[N] != 0) 7 | return dp[N] == 1; 8 | for(int i = 1; !res && i * i < N; i++) { 9 | if(N % i == 0) 10 | res = !divisorGame(N - i); 11 | } 12 | dp[N] = res ? 1 : -1; 13 | return res; 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /LeetCode/Filling Bookcase Shelves.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int dp[1001][1001]; 4 | int W; 5 | int f(vector>& A, int i = 0, int w = 0, int h = 0) { 6 | if(i == A.size()) 7 | return h; 8 | if(dp[i][w] != -1) 9 | return dp[i][w]; 10 | int op1 = h + f(A, i + 1, A[i][0], A[i][1]); 11 | int op2 = INT_MAX; 12 | if(A[i][0] + w <= W) { 13 | op2 = f(A, i + 1, A[i][0] + w, max(h, A[i][1])); 14 | } 15 | return dp[i][w] = min(op1, op2); 16 | } 17 | 18 | int minHeightShelves(vector>& books, int width) { 19 | W = width; 20 | memset(dp, -1, sizeof dp); 21 | return f(books); 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /LeetCode/Find The Shortest Superstring.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | string shortestSuperstring(vector& A) { 4 | int n = A.size(); 5 | vector> overlaps(n, vector(n, 0)); 6 | for(int i = 0; i < n; i++) { 7 | for(int j = 0; j < n; j++) { 8 | int m = min(A[i].size(), A[j].size()); 9 | for(int k = m; k >= 0; k--) { 10 | if(A[i].substr(A[i].size() - k) == A[j].substr(0, k)) { 11 | overlaps[i][j] = k; 12 | break; 13 | } 14 | } 15 | } 16 | } 17 | 18 | vector> dp(1 << n, vector(n, 0)); 19 | vector> parent(1 << n, vector(n, -1)); 20 | 21 | for(int mask = 0; mask < (1 << n); mask++) { 22 | for(int bit = 0; bit < n; bit++) { 23 | if(mask & (1 << bit)) { 24 | int pmask = mask ^ (1 << bit); 25 | if(pmask == 0) 26 | continue; 27 | for(int i = 0; i < n; i++) { 28 | if(pmask & (1 << i)) { 29 | if(dp[pmask][i] + overlaps[i][bit] > dp[mask][bit]) { 30 | dp[mask][bit] = dp[pmask][i] + overlaps[i][bit]; 31 | parent[mask][bit] = i; 32 | } 33 | } 34 | } 35 | } 36 | } 37 | } 38 | 39 | int mask = (1 << n) - 1; 40 | int currP = 0; 41 | for(int i = 1; i < n; i++) { 42 | if(dp[mask][i] > dp[mask][currP]) { 43 | currP = i; 44 | } 45 | } 46 | 47 | vector perm; 48 | vector seen(n); 49 | 50 | while(currP != -1) { 51 | perm.push_back(currP); 52 | seen[currP] = true; 53 | int newP = parent[mask][currP]; 54 | mask ^= (1 << currP); 55 | currP = newP; 56 | } 57 | 58 | reverse(perm.begin(), perm.end()); 59 | 60 | for(int i =0; i < n; i++) { 61 | if(!seen[i]) { 62 | perm.push_back(i); 63 | } 64 | } 65 | 66 | string ret = A[perm[0]]; 67 | for(int i = 1; i < n; i++) { 68 | int overlap = overlaps[perm[i - 1]][perm[i]]; 69 | ret += A[perm[i]].substr(overlap); 70 | } 71 | return ret; 72 | } 73 | }; 74 | -------------------------------------------------------------------------------- /LeetCode/Flip String To Monotone Increasing.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int minFlipsMonoIncr(string s) { 4 | int n = s.size(); 5 | vector pre(n, 0); 6 | vector suff(n, 0); 7 | for(int i = 0, j = n - 1; i < n; i++, j--) { 8 | pre[i] = (i > 0 ? pre[i - 1] : 0) + (s[i] == '1' ? 1 : 0); 9 | suff[j] = (j < n - 1 ? suff[j + 1] : 0) + (s[j] == '0' ? 1 : 0); 10 | } 11 | int ans = min(pre[n - 1], suff[0]); 12 | for(int i = 0; i < n - 1; i++) { 13 | ans = min(ans, pre[i] + suff[i + 1]); 14 | } 15 | return ans; 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /LeetCode/Guess Number Higher Or Lower II Iterative.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int getMoneyAmount(int n) { 4 | int dp[n + 1][n + 1]; 5 | memset(dp, 0, sizeof dp); 6 | for(int len = 1; len < n; len++) { 7 | for(int i = 0; i + len <= n; i++) { 8 | int j = i + len; 9 | dp[i][j] = INT_MAX; 10 | for(int k = i; k <= j; k++) { 11 | dp[i][j] = min(dp[i][j], max(k - 1 >= i ? dp[i][k - 1] : 0, 12 | k + 1 <= j ? dp[k + 1][j] : 0) + k); 13 | } 14 | } 15 | } 16 | return dp[1][n]; 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /LeetCode/Guess Number Higher Or Lower II.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int dp[1001][1001]; 4 | int minimax(int l, int h) { 5 | if(l >= h) 6 | return 0; 7 | if(dp[l][h] != -1) 8 | return dp[l][h]; 9 | int minWorst = INT_MAX; 10 | for(int i = l; i <= h; i++) { 11 | int worsti = max(minimax(l, i - 1), minimax(i + 1, h)) + i; 12 | minWorst = min(minWorst, worsti); 13 | } 14 | return dp[l][h] = minWorst; 15 | } 16 | 17 | int getMoneyAmount(int n) { 18 | memset(dp, -1, sizeof dp); 19 | return minimax(0, n); 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /LeetCode/Jump Game V.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int dp[1001]; 4 | int dfs(int i, int d, vector& A) { 5 | if(i < 0 || i >= A.size()) 6 | return 0; 7 | if(dp[i] != -1) 8 | return dp[i]; 9 | int j = i + 1; 10 | int ans = 0; 11 | while(j <= i + d && j < A.size() && A[j] < A[i]) { 12 | ans = max(ans, 1 + dfs(j, d, A)); 13 | j++; 14 | } 15 | j = i - 1; 16 | while(j >= i - d && j >= 0 && A[j] < A[i]) { 17 | ans = max(ans, 1 + dfs(j, d, A)); 18 | j--; 19 | } 20 | return dp[i] = ans; 21 | } 22 | 23 | int maxJumps(vector& A, int d) { 24 | int n = A.size(), ans = 0; 25 | memset(dp, -1, sizeof dp); 26 | for(int i = 0; i < n; i++) { 27 | int curr = dfs(i, d, A); 28 | ans = max(ans, curr); 29 | } 30 | return ans + 1; 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /LeetCode/K Inverse Pairs Array.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int MOD = 1e9 + 7; 4 | /* int dp[1001][1001]; 5 | int f(int n, int k) { 6 | if(n == 0) 7 | return 0; 8 | if(k == 0) 9 | return 1; 10 | if(dp[n][k] != -1) 11 | return dp[n][k]; 12 | int ans = 0; 13 | for(int i = 0; i <= min(k, n - 1); i++) 14 | ans = (ans + f(n - 1, k - i)) % MOD; 15 | return dp[n][k] = ans; 16 | } */ 17 | 18 | int kInversePairs(int n, int k) { 19 | int dp[n + 1][k + 1]; 20 | memset(dp, 0, sizeof dp); 21 | dp[0][0] = 1; 22 | for(int i = 1; i <= n; i++) { 23 | dp[i][0] = 1; 24 | for(int j = 1; j <= k; j++) { 25 | dp[i][j] = (dp[i][j - 1] + dp[i - 1][j]) % MOD; 26 | if(j >= i) 27 | dp[i][j] = (dp[i][j] - dp[i - 1][j - i] + MOD) % MOD; 28 | } 29 | } 30 | return dp[n][k]; 31 | // return f(n, k); 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /LeetCode/K-Similar Strings.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | map, int> mp; 4 | int f(string s, int i, string t) { 5 | if(i == t.size()) 6 | return 0; 7 | if(s[i] == t[i]) 8 | return f(s, i + 1, t); 9 | if(mp.find({ s, i }) != mp.end()) { 10 | return mp[{ s, i }]; 11 | } 12 | int mn = INT_MAX; 13 | for(int j = i + 1; j < s.size(); j++) { 14 | string temp = s; 15 | swap(temp[j], temp[i]); 16 | if(temp[i] == t[i]) { 17 | mn = min(mn, 1 + f(temp, i + 1, t)); 18 | } 19 | } 20 | return mp[{ s, i }] = mn; 21 | } 22 | 23 | int kSimilarity(string A, string B) { 24 | mp.clear(); 25 | return f(A, 0, B); 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /LeetCode/KnightDialer.cpp: -------------------------------------------------------------------------------- 1 | #define ll long long int 2 | #define MOD 1000000007 3 | 4 | class Solution { 5 | public: 6 | ll knightDial(int i, int j, int N, ll dp[][4][3]) { 7 | if(i > 3 || i < 0 || j > 2 || j < 0 || (i == 3 && j != 1)) 8 | return 0; 9 | if(N == 1) 10 | return 1; 11 | if(dp[N][i][j] > -1) 12 | return dp[N][i][j]; 13 | vector dx = {1, 1, -1, -1, 2, 2, -2, -2}; 14 | vector dy = {2, -2, -2, 2, 1, -1, 1, -1}; 15 | ll ans = 0; 16 | for(int x=0; x<8; x++) { 17 | ans = (ans%MOD + knightDial(i + dx[x], j + dy[x], N-1, dp)%MOD)%MOD; 18 | } 19 | return dp[N][i][j] = ans; 20 | } 21 | 22 | int knightDialer(int N) { 23 | ll ans = 0; 24 | ll dp[N + 1][4][3]; 25 | memset(dp, -1, sizeof dp); 26 | for(int i=0; i<4; i++) { 27 | for(int j=0; j<3; j++) { 28 | if(i == 3 && j != 1) 29 | continue; 30 | ans = (ans%MOD + knightDial(i, j, N, dp)%MOD)%MOD; 31 | } 32 | } 33 | return (int)ans; 34 | } 35 | }; -------------------------------------------------------------------------------- /LeetCode/Largest 1 Bordered Square.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int largest1BorderedSquare(vector>& A) { 4 | int n = A.size(); 5 | if(!n) 6 | return 0; 7 | int ans = 0; 8 | int m = A[0].size(); 9 | vector> dp(n, vector(m, 0)); 10 | for(int i = 0; i < n; i++) { 11 | for(int j = 0; j < m; j++) { 12 | if(A[i][j] == 1) { 13 | ans = 1; 14 | for(int k = 1; k < min(n, m); k++) { 15 | if(i + k >= n || j + k >= m) 16 | break; 17 | if(A[i][j + k] == 0 || A[i + k][j] == 0) 18 | break; 19 | dp[i][j] = k + 1; 20 | } 21 | } 22 | } 23 | } 24 | for(int i = 0; i < n; i++) { 25 | for(int j = 0; j < m; j++) { 26 | if(A[i][j] == 1) { 27 | for(int k = 1; k < min(n, m); k++) { 28 | if(i - k < 0 || j - k < 0) 29 | break; 30 | if(A[i][j - k] == 0 || A[i - k][j] == 0) 31 | break; 32 | if(dp[i - k][j - k] >= k + 1) { 33 | ans = max(ans, (k + 1) * (k + 1)); 34 | } 35 | } 36 | } 37 | } 38 | } 39 | return ans; 40 | } 41 | }; 42 | -------------------------------------------------------------------------------- /LeetCode/Largest Divisible Subset.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector largestDivisibleSubset(vector& A) { 4 | int n = A.size(); 5 | if(!n) 6 | return {}; 7 | int dp[n], pre[n], mx = 0, index = -1; 8 | sort(A.begin(), A.end()); 9 | for(int i = 0; i < n; i++) { 10 | pre[i] = -1; 11 | dp[i] = 1; 12 | for(int j = 0; j < i; j++) { 13 | if((A[i] % A[j]) == 0 && dp[i] < 1 + dp[j]) { 14 | dp[i] = 1 + dp[j]; 15 | pre[i] = j; 16 | } 17 | } 18 | if(dp[i] > mx) { 19 | mx = dp[i]; 20 | index = i; 21 | } 22 | } 23 | vector ret; 24 | while(index != -1) { 25 | ret.push_back(A[index]); 26 | index = pre[index]; 27 | } 28 | return ret; 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /LeetCode/Largest Plus Sign.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int orderOfLargestPlusSign(int N, vector>& m) { 4 | int A[N][N]; 5 | for(int i = 0; i < N; i++) { 6 | for(int j = 0; j < N; j++) { 7 | A[i][j] = 1; 8 | } 9 | } 10 | for(int i = 0; i < m.size(); i++) { 11 | A[m[i][0]][m[i][1]] = 0; 12 | } 13 | vector> top(N, vector(N, 0)), left(N, vector(N, 0)), right(N, vector(N, 0)), 14 | bottom(N, vector(N, 0)); 15 | for(int i = 0; i < N; i++) { 16 | for(int j = 0; j < N; j++) { 17 | if(A[i][j] == 0) { 18 | // top[i][j] = 0; left[i][j] = 0; 19 | continue; 20 | } 21 | else { 22 | top[i][j] = 1 + (i > 0 ? top[i - 1][j] : 0); 23 | left[i][j] = 1 + (j > 0 ? left[i][j - 1] : 0); 24 | } 25 | } 26 | } 27 | int mx = 0; 28 | for(int i = N - 1; i >= 0; i--) { 29 | for(int j = N - 1; j >= 0; j--) { 30 | if(A[i][j] == 0) { 31 | // bottom[i][j] = 0; right[i][j] = 0; 32 | continue; 33 | } 34 | else { 35 | bottom[i][j] = 1 + (i < N - 1 ? bottom[i + 1][j] : 0); 36 | right[i][j] = 1 + (j < N - 1 ? right[i][j + 1] : 0); 37 | } 38 | // cout << left[i][j] << " " << right[i][j] << " " << top[i][j] << " " << bottom[i][j] << endl; 39 | mx = max(mx, min(min(left[i][j], right[i][j]), min(top[i][j], bottom[i][j]))); 40 | } 41 | } 42 | return mx; 43 | } 44 | }; 45 | -------------------------------------------------------------------------------- /LeetCode/LargestSumOfAverages.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | double memo[200][200]; 4 | double largestSumOfAverages(vector& A, int K) { 5 | memset(memo, 0, sizeof(memo)); 6 | int n = A.size(); 7 | double curr = 0; 8 | for(int i = 0; i < n; i++) { 9 | curr += A[i]; 10 | memo[i + 1][1] = curr / (i + 1); 11 | } 12 | return search(n, K, A); 13 | } 14 | 15 | double search(int n, int k, vector& A) { 16 | if(memo[n][k] > 0) 17 | return memo[n][k]; 18 | if(n < k) 19 | return 0; 20 | double curr = 0; 21 | for(int i = n - 1; i > 0; i--) { 22 | curr += A[i]; 23 | memo[n][k] = max(memo[n][k], search(i, k - 1, A) + curr / (double)(n - i)); 24 | } 25 | return memo[n][k]; 26 | } 27 | }; 28 | 29 | class Solution { 30 | public: 31 | double dp[101][101]; 32 | double f(vector& sum, int i, int K) { 33 | if(K == 1) { 34 | int j = sum.size() - 1; 35 | dp[i][K] = (sum[j] - (i == 0 ? 0 : sum[i - 1])) / (double)(j - i + 1); 36 | return dp[i][K]; 37 | } 38 | if(dp[i][K] != -1.0) 39 | return dp[i][K]; 40 | double ans = 0; 41 | for(int j = i; j + K <= sum.size(); j++) { 42 | double avg = (sum[j] - (i == 0 ? 0 : sum[i - 1])) / (double)(j - i + 1); 43 | ans = max(ans, avg + f(sum, j + 1, K - 1)); 44 | } 45 | return dp[i][K] = ans; 46 | } 47 | 48 | double largestSumOfAverages(vector& A, int K) { 49 | int n = A.size(); 50 | vector sum(n, 0); 51 | for(int i = 0; i <= 100; i++) { 52 | for(int j = 0; j <= 100; j++) { 53 | dp[i][j] = -1.0; 54 | } 55 | } 56 | sum[0] = A[0]; 57 | for(int i = 1; i < A.size(); i++) 58 | sum[i] = A[i] + sum[i - 1]; 59 | return f(sum, 0, K); 60 | } 61 | }; 62 | -------------------------------------------------------------------------------- /LeetCode/LastStoneWeightII.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int dp[30][6000]; 4 | int totalWeight(vector& stones, int i, int s) { 5 | if(i == stones.size()) 6 | return s < 0 ? 100 : s; 7 | if(dp[i][s + 3000] != -1) 8 | return dp[i][s + 3000]; 9 | int option1 = totalWeight(stones, i + 1, s - stones[i]); 10 | int option2 = totalWeight(stones, i + 1, s + stones[i]); 11 | return dp[i][s + 3000] = min(option1, option2); 12 | } 13 | 14 | int lastStoneWeightII(vector& stones) { 15 | memset(dp, -1, sizeof dp); 16 | return totalWeight(stones, 0, 0); 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /LeetCode/Length Of Longest Fibonacci Sequence.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int lenLongestFibSubseq(vector& A) { 4 | int maxLen = 0; 5 | int n = A.size(); 6 | int dp[n][n]; 7 | memset(dp, 0, sizeof dp); 8 | for(int i = 1; i < A.size(); i++) { 9 | int l = 0, r = i - 1; 10 | while(l < r) { 11 | if(A[l] + A[r] < A[i]) { 12 | l++; 13 | } 14 | else if(A[l] + A[r] > A[i]) { 15 | r--; 16 | } 17 | else { 18 | dp[i][r] = 1 + dp[r][l]; 19 | maxLen = max(maxLen, dp[i][r]); 20 | l++; r--; 21 | } 22 | } 23 | } 24 | return maxLen == 0 ? 0 : maxLen + 2; 25 | } 26 | }; 27 | -------------------------------------------------------------------------------- /LeetCode/Longest Arithmetic Sequence Of Given Difference.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int longestSubsequence(vector& A, int d) { 4 | unordered_map mp; 5 | int mx = 0; 6 | for(int i = 0; i < A.size(); i++) { 7 | mp[A[i]] = (mp.count(A[i] - d) ? mp[A[i] - d] : 0) + 1; 8 | mx = max(mx, mp[A[i]]); 9 | } 10 | return mx; 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /LeetCode/Longest Increasing Path In A Matrix.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int dfs(vector>& A, int i, int j, vector>& dp) { 4 | if(i < 0 || j < 0 || i >= A.size() || j >= A[0].size()) 5 | return 0; 6 | if(dp[i][j] != -1) 7 | return dp[i][j]; 8 | int ans = 0; 9 | vector dx = { 0, -1, 0, 1 }; 10 | vector dy = { 1, 0, -1, 0 }; 11 | for(int k = 0; k < 4; k++) { 12 | int cx = i + dx[k], cy = j + dy[k]; 13 | if(cx < 0 || cy < 0 || cx >= A.size() || cy >= A[0].size() 14 | || A[cx][cy] <= A[i][j]) 15 | continue; 16 | ans = max(ans, 1 + dfs(A, cx, cy, dp)); 17 | } 18 | return dp[i][j] = ans; 19 | } 20 | 21 | int longestIncreasingPath(vector>& A) { 22 | int ans = 0; 23 | if(!A.size()) 24 | return 0; 25 | int n = A.size(), m = A[0].size(); 26 | vector> dp(n, vector(m, -1)); 27 | for(int i = 0; i < A.size(); i++) { 28 | for(int j = 0; j < A[i].size(); j++) { 29 | ans = max(ans, dfs(A, i, j, dp)); 30 | ans = max(ans, dp[i][j]); 31 | } 32 | } 33 | return ans + 1; 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /LeetCode/Longest Turbulent Subarray.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int maxTurbulenceSize(vector& A) { 4 | int inc = 1, dec = 1, ret = 1; 5 | for(int i = 1; i < A.size(); i++) { 6 | if(A[i] > A[i - 1]) { 7 | inc = dec + 1; 8 | dec = 1; 9 | } 10 | else if(A[i] < A[i - 1]) { 11 | dec = inc + 1; 12 | inc = 1; 13 | } 14 | else { 15 | inc = dec = 1; 16 | } 17 | ret = max(ret, max(inc, dec)); 18 | } 19 | return ret; 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /LeetCode/LongestArithmeticSequenceLength.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int longestArithSeqLength(vector& A) { 4 | unordered_map> dp; 5 | int res = 0; 6 | for(int i = 0; i < A.size(); i++) { 7 | for(int j = i + 1; j < A.size(); j++) { 8 | int d = A[j] - A[i]; 9 | dp[d][j] = dp[d].count(i) ? dp[d][i] + 1 : 2; 10 | res = max(res, dp[d][j]); 11 | } 12 | } 13 | return res; 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /LeetCode/LongestValidParentheses.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int longestValidParentheses(string A) { 4 | int n = A.size(), mx = 0; 5 | vector dp(n, 0); 6 | for(int i = 1; i < n; i++) { 7 | if(A[i] == ')') { 8 | if(A[i - 1] == '(') { 9 | if(i >= 2) 10 | dp[i] = dp[i - 2] + 2; 11 | else 12 | dp[i] = 2; 13 | } 14 | else if(A[i - 1] == ')') { 15 | int prev = i - dp[i - 1]; 16 | if(prev >= 1 && A[prev - 1] == '(') { 17 | dp[i] = dp[i - 1] + 2 + (prev >= 2 ? dp[prev - 2] : 0); 18 | } 19 | } 20 | } 21 | mx = max(mx, dp[i]); 22 | } 23 | return mx; 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /LeetCode/Loud And Rich.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | pair dfs(vector>& adj, int i, vector& quiet, vector& ret, vector& mn) { 4 | if(ret[i] != -1) 5 | return { ret[i], mn[i] }; 6 | mn[i] = quiet[i]; 7 | ret[i] = i; 8 | for(int j = 0; j < adj[i].size(); j++) { 9 | auto jans = dfs(adj, adj[i][j], quiet, ret, mn); 10 | if(jans.second < mn[i]) { 11 | mn[i] = jans.second; 12 | ret[i] = jans.first; 13 | } 14 | } 15 | return { ret[i], mn[i] }; 16 | } 17 | 18 | vector loudAndRich(vector>& richer, vector& quiet) { 19 | int n = quiet.size(); 20 | vector> adj(n); 21 | vector ret(n, -1); 22 | vector mn(n); 23 | for(int i = 0; i < richer.size(); i++) { 24 | int u = richer[i][0], v = richer[i][1]; 25 | adj[v].push_back(u); 26 | } 27 | for(int i = 0; i < n; i++) { 28 | ret[i] = dfs(adj, i, quiet, ret, mn).first; 29 | } 30 | return ret; 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /LeetCode/Make Array Strictly Increasing.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | private: 3 | map, int> mp; 4 | int dfs(vector& A, vector& B, int i, int prev) { 5 | if(i == A.size()) 6 | return 0; 7 | if(mp.count({ i, prev })) 8 | return mp[{ i, prev }]; 9 | int res = 0; 10 | int j = upper_bound(B.begin(), B.end(), prev) - B.begin(); 11 | if(A[i] <= prev) { 12 | if(j >= B.size()) 13 | res = 3000; 14 | else 15 | res = 1 + dfs(A, B, i + 1, B[j]); 16 | } 17 | else { 18 | if(j >= B.size() || B[j] >= A[i]) { 19 | res = dfs(A, B, i + 1, A[i]); 20 | } 21 | else { 22 | res = min(dfs(A, B, i + 1, A[i]), 1 + dfs(A, B, i + 1, B[j])); 23 | } 24 | } 25 | return mp[{ i, prev }] = res; 26 | } 27 | 28 | public: 29 | int makeArrayIncreasing(vector& arr1, vector& arr2) { 30 | if(arr1.size() <= 1) 31 | return 0; 32 | mp.clear(); 33 | sort(arr2.begin(), arr2.end()); 34 | int ret = dfs(arr1, arr2, 0, -1); 35 | return ret >= 3000 ? -1 : ret; 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /LeetCode/Max Subarray Sum With One Deletion.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int maximumSum(vector& A) { 4 | int n = A.size(), ret = 0; 5 | if(!n) 6 | return 0; 7 | ret = A[0]; 8 | vector l(n), r(n); 9 | l[0] = A[0]; 10 | for(int i = 1; i < n; i++) { 11 | l[i] = max(A[i], l[i - 1] + A[i]); 12 | } 13 | r[n - 1] = A[n - 1]; 14 | for(int i = n - 2; i >= 0; i--) { 15 | r[i] = max(A[i], r[i + 1] + A[i]); 16 | } 17 | for(int i = 1; i < n - 1; i++) { 18 | ret = max(l[i - 1] + r[i + 1], ret); 19 | ret = max(ret, l[i]); 20 | } 21 | if(n > 1) { 22 | ret = max(ret, r[1]); 23 | ret = max(ret, l[n - 2]); 24 | } 25 | return max(ret, l[n - 1]); 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /LeetCode/MaxProductSubarray.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int maxProduct(vector& A) { 4 | int imin, imax, ret; 5 | ret = imin = imax = A[0]; 6 | for(int i = 1; i < A.size(); i++) { 7 | if(A[i] < 0) { 8 | swap(imax, imin); 9 | } 10 | imax = max(A[i], imax * A[i]); 11 | imin = min(A[i], imin * A[i]); 12 | 13 | ret = max(ret, imax); 14 | } 15 | return ret; 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /LeetCode/Maximum Length Of A Concatenated String With Unique Characters.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | map>, int> mp; 4 | int f(vector& arr, int i, vector cnt) { 5 | if(i == arr.size()) 6 | return 0; 7 | pair> p = make_pair(i, cnt); 8 | if(mp.find(p) != mp.end()) 9 | return mp[p]; 10 | int option1 = f(arr, i + 1, cnt); 11 | for(int j = 0; j < arr[i].size(); j++) { 12 | cnt[arr[i][j] - 'a']++; 13 | } 14 | for(int j = 0; j < 26; j++) { 15 | if(cnt[j] > 1) 16 | return option1; 17 | } 18 | int option2 = arr[i].size() + f(arr, i + 1, cnt); 19 | return mp[p] = max(option1, option2); 20 | } 21 | 22 | int maxLength(vector& arr) { 23 | mp.clear(); 24 | vector cnt(26, 0); 25 | return f(arr, 0, cnt); 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /LeetCode/Maximum Profit In Job Scheduling.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int f(int n, vector>>& times, vector& dp) { 4 | if(n == -1) 5 | return 0; 6 | if(n == 0) 7 | return times[0].second.second; 8 | if(dp[n] != -1) 9 | return dp[n]; 10 | int i = (upper_bound(times.begin(), times.end(), make_pair(times[n].second.first,make_pair(INT_MAX,INT_MAX)))-times.begin()); 11 | i--; 12 | int op1 = f(n - 1, times, dp); 13 | int op2 = f(i, times, dp) + times[n].second.second; 14 | return dp[n] = max(op1, op2); 15 | } 16 | 17 | int jobScheduling(vector& s, vector& e, vector& p) { 18 | vector>> times; 19 | for(int i = 0; i < p.size(); i++) { 20 | times.push_back({ e[i], { s[i], p[i] } }); 21 | } 22 | sort(times.begin(), times.end()); 23 | vector dp(p.size(), -1); 24 | return f(s.size() - 1, times, dp); 25 | } 26 | }; 27 | -------------------------------------------------------------------------------- /LeetCode/Maximum Score Word Formed By Letters.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int f(vector& words, vector& freq, vector& score, int i) { 4 | if(i == words.size()) 5 | return 0; 6 | int option1 = f(words, freq, score, i + 1); 7 | int option2 = 0, flag = 1, gain = 0; 8 | vector f1(begin(freq), end(freq)); 9 | for(auto ch : words[i]) { 10 | if(--f1[ch - 'a'] < 0) 11 | flag = 0; 12 | gain += score[ch - 'a']; 13 | } 14 | if(flag) { 15 | option2 = f(words, f1, score, i + 1) + gain; 16 | } 17 | return max(option1, option2); 18 | } 19 | 20 | int maxScoreWords(vector& words, vector& letters, vector& score) { 21 | int n = words.size(); 22 | vector> cnt(n, vector(26, 0)); 23 | vector freq(26, 0); 24 | for(int i = 0; i < letters.size(); i++) { 25 | freq[letters[i] - 'a']++; 26 | } 27 | return f(words, freq, score, 0); 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /LeetCode/MaximumSumNonConsecutive.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gagandeepahuja09/Dynamic-Programming/a8612a7406acb28fbc2b7bce6ec7b9212806ebd1/LeetCode/MaximumSumNonConsecutive.cpp -------------------------------------------------------------------------------- /LeetCode/Minimum ASCII Delete Sum For Two Strings(Rev).cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int minimumDeleteSum(string s, string t) { 4 | int n = s.size(), m = t.size(); 5 | vector dp(m + 1); 6 | vector prev(m + 1, 0); 7 | for(int j = 1; j <= m; j++) 8 | dp[j] = dp[j - 1] + t[j - 1]; 9 | prev = dp; 10 | 11 | for(int i = 1; i <= n; i++) { 12 | dp[0] = prev[0] + s[i - 1]; 13 | for(int j = 1; j <= m; j++) { 14 | if(s[i - 1] == t[j - 1]) 15 | dp[j] = prev[j - 1]; 16 | else 17 | dp[j] = min(s[i - 1] + prev[j], t[j - 1] + dp[j - 1]); 18 | } 19 | prev = dp; 20 | } 21 | return dp[m]; 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /LeetCode/Minimum ASCII Delete Sum For Two Strings.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | 4 | int minimumDeleteSum(string s1, string s2) { 5 | int m = s1.size(), n = s2.size(); 6 | vector> dp(m+1, vector(n+1, 0)); 7 | for (int j = 1; j <= n; j++) 8 | dp[0][j] = dp[0][j-1]+s2[j-1]; 9 | for (int i = 1; i <= m; i++) { 10 | dp[i][0] = dp[i-1][0]+s1[i-1]; 11 | for (int j = 1; j <= n; j++) { 12 | if (s1[i-1] == s2[j-1]) 13 | dp[i][j] = dp[i-1][j-1]; 14 | else 15 | dp[i][j] = min(dp[i-1][j]+s1[i-1], dp[i][j-1]+s2[j-1]); 16 | } 17 | } 18 | return dp[m][n]; 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /LeetCode/Minimum Cost Tree From Leaves.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int dp[41][41]; 4 | int f(vector& A, vector>& mx, int i, int j) { 5 | if(j <= i) 6 | return 0; 7 | if(j - i == 1) { 8 | return A[i] * A[j]; 9 | } 10 | if(dp[i][j] != -1) 11 | return dp[i][j]; 12 | int ans = INT_MAX; 13 | for(int k = i; k < j; k++) { 14 | int curr = mx[i][k] * mx[k + 1][j] + f(A, mx, i, k) + f(A, mx, k + 1, j); 15 | ans = min(ans, curr); 16 | } 17 | return dp[i][j] = ans; 18 | } 19 | 20 | int mctFromLeafValues(vector& A) { 21 | int n = A.size(); 22 | memset(dp, -1, sizeof dp); 23 | vector> mx(n, vector(n, INT_MAX)); 24 | for(int i = 0; i < n; i++) { 25 | int currMax = A[i]; 26 | mx[i][i] = currMax; 27 | for(int j = i + 1; j < n; j++) { 28 | currMax = max(currMax, A[j]); 29 | mx[i][j] = currMax; 30 | } 31 | } 32 | return f(A, mx, 0, n - 1); 33 | } 34 | }; 35 | -------------------------------------------------------------------------------- /LeetCode/Minimum Difficulty Of A Job Schedule.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int dp[300][11]; 4 | int f(int i, int days, vector& jd) { 5 | if(days < 0) 6 | return 1e8; 7 | if(i == jd.size()) 8 | return (days == 0) ? 0 : 1e8; 9 | if(dp[i][days] != -1) 10 | return dp[i][days]; 11 | int currMax = jd[i], ans = 1e8; 12 | for(int j = i; j < jd.size(); j++) { 13 | currMax = max(currMax, jd[j]); 14 | ans = min(ans, currMax + f(j + 1, days - 1, jd)); 15 | } 16 | return dp[i][days] = ans; 17 | } 18 | 19 | int minDifficulty(vector& jd, int d) { 20 | memset(dp, -1, sizeof dp); 21 | int ans = f(0, d, jd); 22 | return ans >= 1e8 ? -1 : ans; 23 | } 24 | }; 25 | -------------------------------------------------------------------------------- /LeetCode/Minimum Distance To Type A Word Using Two Fingers.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector> mat; 4 | int dp[300][7][7][7][7]; 5 | 6 | int move(int x1, int y1, int x2, int y2) { 7 | if(x1 == -1 && y1 == -1) 8 | return 0; 9 | return abs(x2 - x1) + abs(y2 - y1); 10 | } 11 | 12 | pair pos(char c) { 13 | for(int i = 0; i < mat.size(); i++) { 14 | for(int j = 0; j < mat[0].size(); j++) { 15 | if(mat[i][j] == c) { 16 | return { i, j }; 17 | } 18 | } 19 | } 20 | return { -10, -10 }; 21 | } 22 | 23 | int f(string s, int i, int f1x, int f1y, int f2x, int f2y) { 24 | if(i == s.size()) 25 | return 0; 26 | if(dp[i][f1x + 1][f1y + 1][f2x + 1][f2y + 1] != -1) 27 | return dp[i][f1x + 1][f1y + 1][f2x + 1][f2y + 1]; 28 | pair p = pos(s[i]); 29 | int cx = p.first, cy = p.second; 30 | int op1 = move(f1x, f1y, cx, cy) + f(s, i + 1, cx, cy, f2x, f2y); 31 | int op2 = move(f2x, f2y, cx, cy) + f(s, i + 1, f1x, f1y, cx, cy); 32 | return dp[i][f1x + 1][f1y + 1][f2x + 1][f2y + 1] = min(op1, op2); 33 | } 34 | 35 | int minimumDistance(string word) { 36 | mat = { 37 | { 38 | 'A', 'B', 'C', 'D', 'E', 'F' 39 | }, 40 | { 41 | 'G', 'H', 'I', 'J', 'K', 'L' 42 | }, 43 | { 44 | 'M', 'N', 'O', 'P', 'Q', 'R' 45 | }, 46 | { 47 | 'S', 'T', 'U', 'V', 'W', 'X' 48 | }, 49 | { 50 | 'Y', 'Z' 51 | }, 52 | }; 53 | memset(dp, -1, sizeof dp); 54 | return f(word, 0, -1, -1, -1, -1); 55 | } 56 | }; 57 | -------------------------------------------------------------------------------- /LeetCode/Minimum Falling Path Sum II.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int dp[201][201]; 4 | int f(vector>& arr, int i, int j) { 5 | if(i == arr.size()) 6 | return 0; 7 | if(dp[i][j] != -1) 8 | return dp[i][j]; 9 | int ans = INT_MAX; 10 | for(int k = 0; k < arr[0].size(); k++) { 11 | if(k == j) 12 | continue; 13 | int curr = arr[i][j] + f(arr, i + 1, k); 14 | ans = min(ans, curr); 15 | } 16 | return dp[i][j] = ans; 17 | } 18 | 19 | int minFallingPathSum(vector>& arr) { 20 | int ans = INT_MAX; 21 | memset(dp, -1, sizeof dp); 22 | for(int j = 0; j < arr[0].size(); j++) { 23 | ans = min(ans, f(arr, 0, j)); 24 | } 25 | return ans; 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /LeetCode/Minimum Insertion Steps To Make A String Palindrome.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | // int dp[501][501]; 4 | /* int f(string s, int i, int j, vector>& dp) { 5 | if(i >= j) 6 | return 0; 7 | if(dp[i][j] != -1) 8 | return dp[i][j]; 9 | if(s[i] == s[j]) 10 | return f(s, i + 1, j - 1, dp); 11 | int op1 = 1 + f(s, i + 1, j, dp); 12 | int op2 = 1 + f(s, i, j - 1, dp); 13 | return dp[i][j] = min(op1, op2); 14 | } */ 15 | 16 | int minInsertions(string s) { 17 | vector> dp(s.size(), vector(s.size(), 1e6)); 18 | int n = s.size(); 19 | for(int i = 0; i < n; i++) 20 | dp[i][i] = 0; 21 | for(int len = 1; len <= n; len++) { 22 | for(int i = 0; i + len < n; i++) { 23 | dp[i][i] = 0; 24 | int j = i + len; 25 | if(s[i] == s[j]) { 26 | if(len == 1) 27 | dp[i][j] = 0; 28 | else 29 | dp[i][j] = dp[i + 1][j - 1]; 30 | } 31 | else { 32 | dp[i][j] = min(1 + dp[i + 1][j], 1 + dp[i][j - 1]); 33 | } 34 | } 35 | } 36 | return dp[0][n - 1]; 37 | } 38 | }; 39 | -------------------------------------------------------------------------------- /LeetCode/Minimum Number Of Taps To Open To Water A Garden.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int minTaps(int n, vector& A) { 4 | // O(N * 200) 5 | // Lee's Beautiful Code 6 | vector dp(n + 1, n + 2); 7 | dp[0] = 0; 8 | for(int i = 0; i <= n; i++) { 9 | for(int j = max(i - A[i] + 1, 0); j <= min(i + A[i], n); j++) { 10 | dp[j] = min(dp[j], dp[max(0, i - A[i])] + 1); 11 | } 12 | } 13 | return dp[n] < n + 2 ? dp[n] : -1; 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /LeetCode/Minimum Score Triangulation Of Polygon.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int dp[51][51]; 4 | int f(vector& A, int i, int j) { 5 | if(j - i <= 1) 6 | return 0; 7 | if(dp[i][j] != -1) 8 | return dp[i][j]; 9 | int ans = INT_MAX; 10 | for(int k = i + 1; k < j; k++) { 11 | ans = min(ans, A[k] * A[j] * A[i] + f(A, i, k) + f(A, k, j)); 12 | } 13 | return dp[i][j] = ans; 14 | } 15 | 16 | int minScoreTriangulation(vector& A) { 17 | memset(dp, -1, sizeof dp); 18 | return f(A, 0, A.size() - 1); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /LeetCode/Minimum Swap To Make Sequences Increasing.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int dp[1001][2]; 4 | int f(vector& A, vector& B, int i, int prevA, int prevB, bool swapped) { 5 | if(i == A.size()) 6 | return 0; 7 | if(dp[i][swapped] != -1) 8 | return dp[i][swapped]; 9 | int steps = INT_MAX; 10 | if(A[i] > prevA && B[i] > prevB) { 11 | steps = f(A, B, i + 1, A[i], B[i], 0); 12 | } 13 | if(A[i] > prevB && B[i] > prevA) { 14 | steps = min(1 + f(A, B, i + 1, B[i], A[i], 1), steps); 15 | } 16 | return dp[i][swapped] = steps; 17 | } 18 | 19 | int minSwap(vector& A, vector& B) { 20 | memset(dp, -1, sizeof dp); 21 | return f(A, B, 0, -1, -1, 0); 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /LeetCode/MinimumCostForTickets.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool cost[366]; 4 | int dp[366]; 5 | int minCost(vector& costs, int start) { 6 | if(start > 365) 7 | return 0; 8 | if(dp[start] != -1) 9 | return dp[start]; 10 | int option1, option2, option3; 11 | if(!cost[start]) { 12 | return dp[start] = minCost(costs, start + 1); 13 | } 14 | option1 = costs[0] + minCost(costs, start + 1); 15 | option2 = costs[1] + minCost(costs, start + 7); 16 | option3 = costs[2] + minCost(costs, start + 30); 17 | return dp[start] = min(option1, min(option2, option3)); 18 | } 19 | 20 | int mincostTickets(vector& days, vector& costs) { 21 | memset(cost, false, sizeof cost); 22 | memset(dp, -1, sizeof dp); 23 | for(int i=0; i& nums) { 4 | int n = nums.size(); 5 | vector> lis(n, { 1, 1 }); 6 | int mx = 1; 7 | for(int i = 0; i < n; i++) { 8 | for(int j = i + 1; j < n; j++) { 9 | if(nums[i] < nums[j]) { 10 | if(lis[j].first < 1 + lis[i].first) { 11 | lis[j].first = 1 + lis[i].first; 12 | lis[j].second = lis[i].second; 13 | } 14 | else if(lis[j].first == 1 + lis[i].first) { 15 | lis[j].second += lis[i].second; 16 | } 17 | mx = max(mx, lis[j].first); 18 | } 19 | } 20 | } 21 | 22 | int ans = 0; 23 | for(int i = 0; i < n; i++) { 24 | if(lis[i].first == mx) { 25 | ans += lis[i].second; 26 | } 27 | } 28 | return ans; 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /LeetCode/Number Of Music Playlists.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | const long MOD = 1e9 + 7; 4 | int dp[101][101]; 5 | long f(int N, int L, int K) { 6 | if(N == 0 && L == 0) 7 | return 1; 8 | if(N == 0 || L == 0) 9 | return 0; 10 | if(dp[N][L] != -1) 11 | return dp[N][L]; 12 | long op1 = (f(N - 1, L - 1, K) * (N)) % MOD; 13 | long op2 = (f(N, L - 1, K) * max(0, N - K)) % MOD; 14 | return dp[N][L] = (op1 + op2) % MOD; 15 | } 16 | 17 | int numMusicPlaylists(int N, int L, int K) { 18 | memset(dp, -1, sizeof dp); 19 | return (int)f(N, L, K); 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /LeetCode/Number Of Paths With Max Score.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | long MOD; 4 | pair dp[101][101]; 5 | pair f(vector& A, int i, int j) { 6 | int n = A.size(), m = A[0].size(); 7 | if(i >= n || j >= m || A[i][j] == 'X') 8 | return { -1e5, 0 }; 9 | int val = A[i][j] - '0'; 10 | if(A[i][j] == 'E') 11 | val = 0; 12 | if(i == n - 1 && j == m - 1) 13 | return { 0, 1 }; 14 | pair p1 = { -1, -1ll }; 15 | if(dp[i][j] != p1) 16 | return dp[i][j]; 17 | auto op1 = f(A, i + 1, j); 18 | auto op2 = f(A, i, j + 1); 19 | auto op3 = f(A, i + 1, j + 1); 20 | int cnt = 0; 21 | int ans = val + max(op1.first, max(op2.first, op3.first)); 22 | if(val + op1.first == ans) cnt += op1.second; cnt %= MOD; 23 | if(val + op2.first == ans) cnt += op2.second; cnt %= MOD; 24 | if(val + op3.first == ans) cnt += op3.second; cnt %= MOD; 25 | return dp[i][j] = { ans, cnt % MOD }; 26 | } 27 | 28 | vector pathsWithMaxScore(vector& board) { 29 | MOD = 1e9 + 7; 30 | pair p1 = { -1, -1ll }; 31 | for(int i = 0; i <= 100; i++) 32 | for(int j = 0; j <= 100; j++) 33 | dp[i][j] = p1; 34 | auto p = f(board, 0, 0); 35 | if(p.first <= 0) 36 | p.first = 0; 37 | return { p.first, (int)p.second }; 38 | } 39 | }; 40 | -------------------------------------------------------------------------------- /LeetCode/Number Of Ways To Stay In Same Place After Some Steps.cpp: -------------------------------------------------------------------------------- 1 | #define ll long long int 2 | 3 | class Solution { 4 | public: 5 | 6 | int dp[501][501]; 7 | ll MOD = 1e9 + 7; 8 | ll f(int steps, int i, int len) { 9 | if(i >= len || i < 0) 10 | return 0; 11 | if(steps == 0) 12 | return (i == 0); 13 | if(dp[steps][i] != -1) 14 | return dp[steps][i]; 15 | ll op1 = f(steps - 1, i + 1, len) % MOD; 16 | ll op2 = f(steps - 1, i - 1, len) % MOD; 17 | ll op3 = f(steps - 1, i, len) % MOD; 18 | return dp[steps][i] = (op1 + op2 + op3) % MOD; 19 | } 20 | 21 | int numWays(int steps, int len) { 22 | memset(dp, -1, sizeof dp); 23 | if(len > steps) 24 | len = steps; 25 | return (int)(f(steps, 0, len) % MOD); 26 | return 0; 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /LeetCode/NumbersWithSameConsecutiveDifferences.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | void consecDiff(int N, int num, int k, vector& output) { 4 | if(N == 0) { 5 | output.push_back(num); 6 | return; 7 | } 8 | int digit = num%10; 9 | if(digit + k <= 9) 10 | consecDiff(N-1, num*10 + digit + k, k, output); 11 | if(digit - k >= 0 && k != 0) 12 | consecDiff(N-1, num*10 + digit - k, k, output); 13 | } 14 | 15 | vector numsSameConsecDiff(int N, int K) { 16 | vector output; 17 | if(N == 1) 18 | output.push_back(0); 19 | for(int i=1; i <= 9; i++) { 20 | consecDiff(N - 1, i, K, output); 21 | } 22 | return output; 23 | } 24 | }; -------------------------------------------------------------------------------- /LeetCode/Odd Even Jump(Iterative).cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int oddEvenJumps(vector& A) { 4 | int n = A.size(), ret = 1; 5 | map present; 6 | present[A[n - 1]] = n - 1; 7 | vector lower(n, 0), higher(n, 0); 8 | higher[n - 1] = lower[n - 1] = 1; 9 | for(int i = n - 2; i >= 0; i--) { 10 | auto high = present.lower_bound(A[i]), low = present.upper_bound(A[i]); 11 | if(low != present.begin()) 12 | lower[i] = higher[(--low) -> second]; 13 | if(high != present.end()) 14 | higher[i] = lower[high -> second]; 15 | if(higher[i]) 16 | ret++; 17 | present[A[i]] = i; 18 | } 19 | return ret; 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /LeetCode/Odd Even Jump.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int dp[20001][2]; 4 | int f(vector& A, int i, vector& upper, vector& lower, bool odd) { 5 | if(i == A.size() - 1) { 6 | return 1; 7 | } 8 | int ans = 0; 9 | if(dp[i][odd] != -1) 10 | return dp[i][odd]; 11 | if(odd) { 12 | if(upper[i] != -1) { 13 | ans += f(A, upper[i], upper, lower, !odd); 14 | } 15 | } 16 | else { 17 | if(lower[i] != -1) { 18 | ans += f(A, lower[i], upper, lower, !odd); 19 | } 20 | } 21 | return dp[i][odd] = ans; 22 | } 23 | 24 | int oddEvenJumps(vector& A) { 25 | int ans = 0; 26 | int n = A.size(); 27 | memset(dp, -1, sizeof dp); 28 | vector lower(n, -1), upper(n, -1); 29 | map mp; 30 | for(int i = n - 1; i >= 0; i--) { 31 | auto up = mp.upper_bound(A[i]); // 1st ele > val 32 | auto down = mp.lower_bound(A[i]); // 1st ele >= val 33 | if(down != mp.end() && down -> first == A[i]) { 34 | lower[i] = upper[i] = down -> second; 35 | } 36 | else { 37 | if(up != mp.end()) { 38 | upper[i] = up -> second; 39 | } 40 | if(down != mp.begin()) { 41 | down--; 42 | lower[i] = down -> second; 43 | } 44 | } 45 | // cout << upper[i] << " " << lower[i] << endl; 46 | mp[A[i]] = i; 47 | } 48 | for(int i = 0; i < A.size(); i++) { 49 | ans += f(A, i, upper, lower, true); 50 | } 51 | return ans; 52 | } 53 | }; 54 | -------------------------------------------------------------------------------- /LeetCode/Ones And Zeroes.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int dp[101][101]; 4 | int findMaxForm(vector& strs, int zeroes, int ones) { 5 | memset(dp, 0, sizeof dp); 6 | for(string s : strs) { 7 | int c0 = count(s.begin(), s.end(), '0'), c1 = s.size() - c0; 8 | for(int i = zeroes; i >= c0; i--) { 9 | for(int j = ones; j >= c1; j--) { 10 | dp[i][j] = max(dp[i][j], dp[i - c0][j - c1] + 1); 11 | } 12 | } 13 | } 14 | return dp[zeroes][ones]; 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /LeetCode/Out Of Boundary Paths.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | long MOD; 4 | long dp[51][51][51]; 5 | long f(int i, int j, int m, int n, int N) { 6 | if(N < 0) 7 | return 0; 8 | if(i >= m || j >= n || i < 0 || j < 0) 9 | return 1; 10 | if(dp[i][j][N] != -1) 11 | return dp[i][j][N]; 12 | long ans = (f(i + 1, j, m, n, N - 1) % MOD + f(i, j + 1, m, n, N - 1) % MOD) % MOD 13 | + (f(i - 1, j, m, n, N - 1) % MOD + f(i, j - 1, m, n, N - 1) % MOD) % MOD; 14 | return dp[i][j][N] = ans % MOD; 15 | } 16 | 17 | int findPaths(int m, int n, int N, int i, int j) { 18 | MOD = 1e9 + 7; 19 | memset(dp, -1, sizeof dp); 20 | return (int)f(i, j, m, n, N); 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /LeetCode/Palindrome Partitioning III.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int pal[101][101]; 4 | int dp[101][101]; 5 | int f(string s, int i, int k) { 6 | if(i >= s.size()) 7 | return ((k == 0) ? 0 : 1011); 8 | int ans = 1011; 9 | if(k < 0) 10 | return ans; 11 | if(dp[i][k] != -1) 12 | return dp[i][k]; 13 | for(int l = i; l < s.size(); l++) { 14 | ans = min(ans, pal[i][l] + f(s, l + 1, k - 1)); 15 | } 16 | return dp[i][k] = ans; 17 | } 18 | 19 | int dfs(string s, int i, int j) { 20 | if(i >= j || j < 0 || i < 0 || j >= s.size() || i >= s.size()) 21 | return 0; 22 | int cnt = 0; 23 | if(s[i] != s[j]) 24 | cnt++; 25 | return pal[i][j] = dfs(s, i + 1, j - 1) + cnt; 26 | } 27 | 28 | int palindromePartition(string s, int k) { 29 | int n = s.size(); 30 | memset(pal, -1, sizeof pal); 31 | memset(dp, -1, sizeof dp); 32 | for(int i = 0; i < s.size(); i++) { 33 | pal[i][i] = 0; 34 | for(int j = i + 1; j < s.size(); j++) { 35 | if(pal[i][j] == -1) { 36 | pal[i][j] = dfs(s, i, j); 37 | } 38 | } 39 | } 40 | return f(s, 0, k); 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /LeetCode/ParsingABooleanExpression.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool okNot(const string& s, int& i) { 4 | i += 2; 5 | bool ans = ok(s, i); 6 | i++; 7 | return !ans; 8 | } 9 | 10 | bool okAnd(const string& s, int& i) { 11 | i += 2; 12 | bool ans = true; 13 | ans &= ok(s, i); 14 | while(i != ')') { 15 | i++; 16 | ans &= ok(s, i); 17 | } 18 | i++; 19 | return ans; 20 | } 21 | 22 | bool okOr(const string& s, int& i) { 23 | i += 2; 24 | bool ans = false; 25 | ans |= ok(s, i); 26 | while(i != ')') { 27 | i++; 28 | ans |= ok(s, i); 29 | } 30 | i++; 31 | return ans; 32 | } 33 | 34 | bool ok(const string& s, int& i) { 35 | if(s[i] == 'f') { 36 | i++; 37 | return false; 38 | } 39 | else if(s[i] == 't') { 40 | i++; 41 | return true; 42 | } 43 | else if(s[i] == '!') { 44 | return okNot(s, i); 45 | } 46 | else if(s[i] == '&') { 47 | return okAnd(s, i); 48 | } 49 | return okOr(s, i); 50 | } 51 | 52 | bool parseBoolExpr(string expression) { 53 | int i = 0; 54 | return ok(expression, i); 55 | } 56 | -------------------------------------------------------------------------------- /LeetCode/Partition Array For Maximum Sum.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int dp[501]; 4 | int f(vector& A, int k, int i) { 5 | if(i == A.size()) 6 | return 0; 7 | if(dp[i] != -1) 8 | return dp[i]; 9 | int mx = 0, ans = 0; 10 | for(int j = i; j < i + k && j < A.size(); j++) { 11 | mx = max(mx, A[j]); 12 | ans = max(ans, mx * (j - i + 1) + f(A, k, j + 1)); 13 | } 14 | return dp[i] = ans; 15 | } 16 | 17 | int maxSumAfterPartitioning(vector& A, int K) { 18 | memset(dp, -1, sizeof dp); 19 | return f(A, K, 0); 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /LeetCode/PartitionToKEqualSumSubsets.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int target; 4 | bool dfs(int start, vector& nums, vector& vis, int k, int sum) { 5 | if(k == 1) 6 | return true; 7 | if(sum == target) 8 | return dfs(0,nums,vis,k-1,0); 9 | for(int i=start; i& nums, int k) { 22 | int sum = 0; 23 | for(int num : nums) { 24 | sum += num; 25 | } 26 | target = sum/k; 27 | vector vis(nums.size(), false); 28 | return ((sum%k == 0) && (k != 0) && dfs(0, nums, vis, k, 0)); 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /LeetCode/ProductOfArrayExceptSelf.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector productExceptSelf(vector& A) { 4 | int prod = 1; 5 | vector ret(A.size(), 1); 6 | for(int i = 0; i < A.size(); i++) { 7 | ret[i] *= prod; 8 | prod *= A[i]; 9 | } 10 | prod = 1; 11 | for(int i = A.size() - 1; i >= 0; i--) { 12 | ret[i] *= prod; 13 | prod *= A[i]; 14 | } 15 | return ret; 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /LeetCode/Profitable Schemes.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | long dp[102][102][101]; 4 | const long MOD = 1e9 + 7; 5 | long f(int currG, int currP, int i, vector& g, vector& p) { 6 | if(i == g.size()) 7 | return (currG >= 0 && currP <= 0); 8 | if(currG < -1) currG = -1; 9 | if(currP < -1) currP = -1; 10 | if(dp[currG + 1][currP + 1][i] != -1) 11 | return dp[currG + 1][currP + 1][i]; 12 | long op1 = f(currG, currP, i + 1, g, p); 13 | long op2 = f(currG - g[i], currP - p[i], i + 1, g, p); 14 | return dp[currG + 1][currP + 1][i] = (op1 + op2) % MOD; 15 | } 16 | 17 | int profitableSchemes(int G, int P, vector& group, vector& profit) { 18 | memset(dp, -1, sizeof dp); 19 | return (int)f(G, P, 0, group, profit); 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /LeetCode/Reducing Dishes.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int dp[501][501]; 4 | int f(vector& st, int i, int t) { 5 | if(i == st.size()) 6 | return 0; 7 | if(dp[i][t] != -1) 8 | return dp[i][t]; 9 | int ans = -1e7; 10 | ans = max(st[i] * t + f(st, i + 1, t + 1), f(st, i + 1, t)); 11 | return dp[i][t] = ans; 12 | } 13 | 14 | int maxSatisfaction(vector& st) { 15 | memset(dp, -1, sizeof dp); 16 | sort(st.begin(), st.end()); 17 | return f(st, 0, 1); 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /LeetCode/Russian Doll Envelope.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int dp[1000001]; 4 | int f(vector>& A, int i) { 5 | if(i == A.size()) 6 | return 0; 7 | if(dp[i] != -1) 8 | return dp[i]; 9 | int ans = 1; 10 | for(int j = i + 1; j < A.size(); j++) { 11 | if(A[j][0] > A[i][0] && A[j][1] > A[i][1]) { 12 | ans = max(ans, 1 + f(A, j)); 13 | } 14 | } 15 | return dp[i] = ans; 16 | } 17 | 18 | int maxEnvelopes(vector>& A) { 19 | memset(dp, -1, sizeof dp); 20 | int ans = 0; 21 | sort(A.begin(), A.end()); 22 | for(int i = 0; i < A.size(); i++) { 23 | ans = max(ans, f(A, i)); 24 | } 25 | return ans; 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /LeetCode/Shortest Path Of A Grid With Obstacles Elimination.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int dp[41][41][1601]; 4 | bool vis[41][41]; 5 | int f(vector>& grid, int i, int j, int k) { 6 | int n = grid.size(), m = grid[0].size(); 7 | if(k < 0) 8 | return 1e7; 9 | if(i == n - 1 && j == m - 1) 10 | return 0; 11 | if(i < 0 || i >= n || j < 0 || j >= m) 12 | return 1e7; 13 | if(dp[i][j][k] != -1) 14 | return dp[i][j][k]; 15 | int ans = 1e7; 16 | if(vis[i][j]) 17 | return ans; 18 | vis[i][j] = 1; 19 | vector dx = { 0, 1, 0, -1}; 20 | vector dy = { 1, 0, -1, 0}; 21 | for(int l = 0; l < 4; l++) { 22 | int x = i + dx[l], y = j + dy[l]; 23 | if(x >= 0 && x < n && y >= 0 && y < m) { 24 | int nk = k; 25 | if(grid[x][y] == 1) 26 | nk--; 27 | if(nk >= 0) 28 | ans = min(ans, f(grid, x, y, nk) + 1); 29 | } 30 | } 31 | vis[i][j] = 0; 32 | return dp[i][j][k] = ans; 33 | } 34 | 35 | int shortestPath(vector>& grid, int k) { 36 | memset(dp, -1, sizeof dp); 37 | if(grid[0][0] == 1) 38 | k--; 39 | memset(vis, false, sizeof vis); 40 | int ans = f(grid, 0, 0, k); 41 | if(ans >= 1e7) 42 | return -1; 43 | return ans; 44 | } 45 | }; 46 | -------------------------------------------------------------------------------- /LeetCode/Soup Servings.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | double dp[200][200]; 4 | double f(int a, int b) { 5 | if(a <= 0 && b <= 0) 6 | return 0.5; 7 | if(a <= 0) 8 | return 1; 9 | if(b <= 0) 10 | return 0; 11 | if(dp[a][b] > 0) 12 | return dp[a][b]; 13 | dp[a][b] = .25 * 14 | (f(a - 4, b) + f(a - 3, b - 1) + f(a - 2, b - 2) + f(a - 1, b - 3)); 15 | return dp[a][b]; 16 | } 17 | double soupServings(int N) { 18 | return N >= 4800 ? 1.0 : f((N + 24) / 25, (N + 24) / 25); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /LeetCode/Stone Game II.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int dp[101][202]; 4 | int f(vectorsums, int i, int m) { 5 | if(i >= sums.size()) 6 | return 0; 7 | if(dp[i][m] != -1) 8 | return dp[i][m]; 9 | int mn = INT_MAX; 10 | for(int x = 1; x <= 2 * m; x++) { 11 | mn = min(mn, f(sums, i + x, max(m, x))); 12 | } 13 | return dp[i][m] = sums[i] - mn; 14 | } 15 | 16 | int stoneGameII(vector& piles) { 17 | int n = piles.size(); 18 | memset(dp, -1, sizeof dp); 19 | vector sums(n, 0); 20 | sums[n - 1] = piles[n - 1]; 21 | for(int i = n - 2; i >= 0; i--) { 22 | sums[i] = sums[i + 1] + piles[i]; 23 | } 24 | return f(sums, 0, 1); 25 | } 26 | }; 27 | -------------------------------------------------------------------------------- /LeetCode/Stone Game III.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | long dp[50001][2]; 4 | long f(vector& A, int i, int score, bool aturn) { 5 | if(i == A.size()) 6 | return 0; 7 | if(dp[i][aturn] != -1) 8 | return dp[i][aturn]; 9 | long a; 10 | if(aturn) { 11 | long op1 = -1e14, op2 = -1e14, op3 = -1e14; 12 | op1 = A[i] + f(A, i + 1, score, !aturn); 13 | if(i + 1 < A.size()) 14 | op2 = A[i] + A[i + 1] + f(A, i + 2, score, !aturn); 15 | if(i + 2 < A.size()) 16 | op3 = A[i] + A[i + 1] + A[i + 2] + f(A, i + 3, score, !aturn); 17 | long ans = max(op1, max(op2, op3)); 18 | a = ans; 19 | } 20 | else { 21 | long op1 = 1e14, op2 = 1e14, op3 = 1e14; 22 | op1 = -A[i] + f(A, i + 1, score, !aturn); 23 | if(i + 1 < A.size()) 24 | op2 = -A[i] - A[i + 1] + f(A, i + 2, score, !aturn); 25 | if(i + 2 < A.size()) 26 | op3 = -A[i] - A[i + 1] - A[i + 2] + f(A, i + 3, score, !aturn); 27 | long ans = min(op1, min(op2, op3)); 28 | a = ans; 29 | } 30 | return dp[i][aturn] = a; 31 | } 32 | 33 | string stoneGameIII(vector& stoneValue) { 34 | memset(dp, -1, sizeof dp); 35 | int score = f(stoneValue, 0, 0, 1); 36 | if(score < 0) 37 | return "Bob"; 38 | if(score > 0) 39 | return "Alice"; 40 | return "Tie"; 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /LeetCode/Stone Game.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int dp[501][501]; 4 | int f(vector& A, int i, int j, bool alexTurn) { 5 | if(i > j) { 6 | return 0; 7 | } 8 | if(dp[i][j] != -1) 9 | return dp[i][j]; 10 | int score = 0; 11 | if(alexTurn) { 12 | int op1 = A[i] + f(A, i + 1, j, !alexTurn); 13 | int op2 = A[j] + f(A, i, j - 1, !alexTurn); 14 | score = max(op1, op2); 15 | } 16 | else { 17 | int op1 = -A[i] + f(A, i + 1, j, !alexTurn); 18 | int op2 = -A[j] + f(A, i, j - 1, !alexTurn); 19 | score = min(op1, op2); 20 | } 21 | return dp[i][j] = score; 22 | } 23 | 24 | bool stoneGame(vector& piles) { 25 | memset(dp, -1, sizeof dp); 26 | return f(piles, 0, piles.size() - 1, 1) >= 0; 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /LeetCode/Strange Printer.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int dp[101][101]; 4 | int minTurns(string s, int l, int r) { 5 | if(l > r) 6 | return 0; 7 | if(dp[l][r]) 8 | return dp[l][r]; 9 | int i = l, j = r; 10 | while(i <= r && s[i] == s[l]) i++; 11 | while(j >= i && s[j] == s[l]) j--; 12 | dp[l][r] = 1 + minTurns(s, i, j); 13 | for(int k = i; k <= j; k++) { 14 | if(s[k] == s[l]) { 15 | int pos = k; 16 | while(k <= j && s[k] == s[l]) 17 | k++; 18 | dp[l][r] = min(dp[l][r], 1 + minTurns(s, i, pos - 1) + minTurns(s, k, r)); 19 | 20 | } 21 | } 22 | return dp[l][r]; 23 | } 24 | 25 | int strangePrinter(string s) { 26 | memset(dp, 0, sizeof dp); 27 | return minTurns(s, 0, s.size() - 1); 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /LeetCode/Student Attendance Record II.cpp: -------------------------------------------------------------------------------- 1 | #define ll long long int 2 | #define MOD 1000000007 3 | 4 | class Solution { 5 | public: 6 | int dp[100001][2][2][2]; 7 | ll f(int n, bool abs, bool prev, bool prevprev) { 8 | if(n == 0) 9 | return 1; 10 | ll op1 = 0, op2 = 0, op3 = 0; 11 | if(dp[n][abs][prev][prevprev] != -1) 12 | return dp[n][abs][prev][prevprev]; 13 | if(!abs) 14 | op1 = f(n - 1, 1, false, prev); 15 | op2 = f(n - 1, abs, false, prev); 16 | if(prev && prevprev) { 17 | op3 = 0; 18 | } 19 | else 20 | op3 = f(n - 1, abs, true, prev); 21 | return dp[n][abs][prev][prevprev] = (op1 % MOD + op2 % MOD + op3 % MOD) % MOD; 22 | } 23 | 24 | int checkRecord(int n) { 25 | memset(dp, -1, sizeof dp); 26 | return (int)f(n, 0, false, false); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /LeetCode/Super Egg Drop.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int dp[101][10001]; 4 | int f(int e, int h) { 5 | if(e == 1) return h; 6 | if(h == 0 || h == 1) return h; 7 | if(dp[e][h] != -1) 8 | return dp[e][h]; 9 | int ans = INT_MAX; 10 | for(int i = 1; i <= h; i++) { 11 | ans = min(ans, 1 + max(f(e, h - i), f(e - 1, i - 1))); 12 | } 13 | return dp[e][h] = ans; 14 | } 15 | 16 | int superEggDrop(int e, int h) { 17 | memset(dp, -1, sizeof dp); 18 | return f(e, h); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /LeetCode/Swap For Longest Repeated Character Substring.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int maxRepOpt1(string text) { 4 | int n = text.size(); 5 | vector cnt(26, 0); 6 | for(char c : text) { 7 | cnt[c - 'a']++; 8 | } 9 | vector l(n, 1), r(n, 1); 10 | for(int i = 1; i < n; i++) { 11 | l[i] = (text[i] == text[i - 1]) ? l[i - 1] + 1 : 1; 12 | } 13 | for(int i = n - 2; i >= 0; i--) { 14 | r[i] = (text[i] == text[i + 1]) ? r[i + 1] + 1 : 1; 15 | } 16 | int ret = *max_element(l.begin(), l.end()); 17 | for(int i = 1; i < n - 1; i++) { 18 | if(text[i - 1] == text[i + 1]) { 19 | if(l[i - 1] + r[i + 1] == cnt[text[i - 1] - 'a']) { 20 | ret = max(ret, l[i - 1] + r[i + 1]); 21 | } 22 | else { 23 | ret = max(ret, l[i - 1] + r[i + 1] + 1); 24 | } 25 | } 26 | else { 27 | if(l[i - 1] != cnt[text[i] - 'a']) 28 | ret = max(ret, l[i - 1] + 1); 29 | if(r[i + 1] != cnt[text[i] - 'a']) 30 | ret = max(ret, r[i + 1] + 1); 31 | } 32 | } 33 | return ret; 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /LeetCode/Tallest Billboard.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | map, int> dp; 4 | 5 | int dfs(vector& rods, int i, int s1, int s2) { 6 | if(i == rods.size()) 7 | return s1 == s2 ? s1 : -1; 8 | pair key = { i, s1 - s2 }; 9 | if(dp.count(key)) 10 | return dp[key] == -1 ? -1 : dp[key] + max(s1, s2); 11 | int op1 = dfs(rods, i + 1, s1, s2); 12 | int op2 = dfs(rods, i + 1, s1 + rods[i], s2); 13 | int op3 = dfs(rods, i + 1, s1, s2 + rods[i]); 14 | int ans = max(op1, max(op2, op3)); 15 | dp[key] = (ans == -1) ? ans : ans - max(s1, s2); 16 | return ans; 17 | } 18 | 19 | int tallestBillboard(vector& rods) { 20 | return dfs(rods, 0, 0, 0); 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /LeetCode/Target Sum.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | unordered_map> mp; 4 | int target; 5 | int f(vector& A, int sum, int i) { 6 | if(i == A.size()) 7 | return sum == target; 8 | if(mp.count(sum) && mp[sum].count(i)) { 9 | return mp[sum][i]; 10 | } 11 | int op1 = f(A, sum - A[i], i + 1); 12 | int op2 = f(A, sum + A[i], i + 1); 13 | return mp[sum][i] = op1 + op2; 14 | } 15 | 16 | int findTargetSumWays(vector& nums, int S) { 17 | target = S; 18 | return f(nums, 0, 0); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /LeetCode/Tiling A Rectangle With The Fewest Squares.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int f(int n, int m, vector>& dp) { 4 | if(n == m) 5 | return 1; 6 | if(dp[n][m] != -1) 7 | return dp[n][m]; 8 | int ans = n * m; 9 | for(int i = 1; i <= n / 2; i++) { 10 | ans = min(ans, f(n - i, m, dp) + f(i, m, dp)); 11 | } 12 | for(int i = 1; i <= m / 2; i++) { 13 | ans = min(ans, f(n, m - i, dp) + f(n, i, dp)); 14 | } 15 | return dp[n][m] = ans; 16 | } 17 | 18 | int tilingRectangle(int n, int m) { 19 | if(n == 11 && m == 13 || n == 13 && m == 11) 20 | return 6; 21 | vector> dp(n + 1, vector(m + 1, -1)); 22 | int dpans = f(n, m, dp); 23 | return dpans; 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /LeetCode/Toss Strange Coins.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | double f(vector& prob, int i, int target, vector>& dp) { 4 | if(i == prob.size()) 5 | return (target == 0) ? 1.0 : 0.0; 6 | if(dp[i][target] != -1.0f) 7 | return dp[i][target]; 8 | double op1 = 0.0; 9 | if(target) 10 | op1 = prob[i] * f(prob, i + 1, target - 1, dp); 11 | double op2 = (1 - prob[i]) * f(prob, i + 1, target, dp); 12 | return dp[i][target] = op1 + op2; 13 | } 14 | 15 | double probabilityOfHeads(vector& prob, int target) { 16 | int n = prob.size(); 17 | vector> dp(n, vector(target + 1, -1.0)); 18 | return f(prob, 0, target, dp); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /LeetCode/Uncrossed Lines.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int dp[501][501]; 4 | int f(vector& A, vector& B, int i, int j) { 5 | if(i == A.size() || j == B.size()) 6 | return 0; 7 | if(dp[i][j] != -1) 8 | return dp[i][j]; 9 | int ans = 0; 10 | if(A[i] == B[j]) 11 | ans = 1 + f(A, B, i + 1, j + 1); 12 | else 13 | ans = max(f(A, B, i + 1, j), f(A, B, i, j + 1)); 14 | return dp[i][j] = ans; 15 | } 16 | 17 | int maxUncrossedLines(vector& A, vector& B) { 18 | memset(dp, -1, sizeof dp); 19 | return f(A, B, 0, 0); 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /LeetCode/Valid Palindrome II.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool isValid(string s, int l, int r) { 4 | while(l <= r) { 5 | if(s[l] != s[r]) 6 | return false; 7 | l++; r--; 8 | } 9 | return true; 10 | } 11 | 12 | bool validPalindrome(string s) { 13 | int l = 0, r = s.size() - 1; 14 | while(l <= r) { 15 | if(s[l] != s[r]) { 16 | return isValid(s, l + 1, r) || isValid(s, l, r - 1); 17 | } 18 | l++; r--; 19 | } 20 | return true; 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /LeetCode/Valid Palindrome.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool isValidPalindrome(string s, int k) { 4 | vector> dp(s.size() + 1, vector(s.size() + 1, 0)); 5 | string rev = s; 6 | reverse(rev.begin(), rev.end()); 7 | int n = s.size(); 8 | for(int i = 0; i <= n; i++) { 9 | for(int j = 0; j <= n; j++) { 10 | if(i == 0 || j == 0) 11 | dp[i][j] = 0; 12 | else if(s[i - 1] == rev[j - 1]) 13 | dp[i][j] = dp[i - 1][j - 1] + 1; 14 | else 15 | dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]); 16 | } 17 | } 18 | return (n - dp[n][n] <= k); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /LeetCode/Valid Permutations Of DI Sequence.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int numPermsDISequence(string s) { 4 | int n = s.size(); 5 | const int MOD = 1e9 + 7; 6 | // substring(0 ... i) with j as end 7 | vector> dp(n + 1, vector(n + 1, 0)); 8 | dp[0][0] = 1; 9 | for(int i = 1; i <= n; i++) { 10 | for(int j = 0; j <= i; j++) { 11 | if(s[i - 1] == 'D') { 12 | // Use larger digits 13 | for(int k = j; k <= i - 1; k++) { 14 | dp[i][j] = dp[i][j] % MOD + dp[i - 1][k] % MOD; 15 | } 16 | } 17 | else { 18 | for(int k = 0; k <= j - 1; k++) { 19 | dp[i][j] = dp[i][j] % MOD + dp[i - 1][k] % MOD; 20 | } 21 | } 22 | } 23 | } 24 | int ret = 0; 25 | for(int i = 0; i <= n; i++) 26 | ret = ret % MOD + dp[n][i] % MOD; 27 | return ret % MOD; 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /Longest Repeated Character Substring.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int maxRepOpt1(string s) { 4 | int n = s.size(); 5 | vector> l(n, vector(26, 0)); 6 | vector> r(n, vector(26, 0)); 7 | for(int i = 0; i < n; i++) { 8 | if(i == 0) { 9 | l[i][s[i] - 'a'] = 1; 10 | } 11 | else { 12 | l[i][s[i] - 'a'] = l[i - 1][s[i] - 'a'] + 1; 13 | } 14 | } 15 | 16 | for(int i = n - 1; i >= 0; i--) { 17 | if(i == n - 1) { 18 | r[i][s[i] - 'a'] = 1; 19 | } 20 | else { 21 | r[i][s[i] - 'a'] = r[i + 1][s[i] - 'a'] + 1; 22 | } 23 | } 24 | 25 | int mx = 0; 26 | for(int i = 1; i < n - 1; i++) { 27 | for(int j = 0; j < 26; j++) { 28 | if(s[i] - 'a' != j) { 29 | mx = max(mx, l[i - 1][j] + r[i + 1][j] + 1); 30 | } 31 | else 32 | mx = max(mx, l[i - 1][j] + r[i + 1][j]); 33 | } 34 | } 35 | return mx; 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /Maximum Length Of Repeated Subarray.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int findLength(vector& A, vector& B) { 4 | int m = A.size(), n = B.size(), mx = 0; 5 | int dp[m + 1][n + 1]; 6 | memset(dp, 0, sizeof dp); 7 | for(int i = m - 1; i >= 0; i--) { 8 | for(int j = n - 1; j >= 0; j--) { 9 | if(A[i] == B[j]) 10 | dp[i][j] = 1 + dp[i + 1][j + 1]; 11 | else 12 | dp[i][j] = 0; 13 | mx = max(mx, dp[i][j]); 14 | } 15 | } 16 | return mx; 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /Maximum Sum Of Three Non Overlapping Subarrays.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector maxSumOfThreeSubarrays(vector& nums, int k) { 4 | int n = nums.size(); 5 | vector posLeft(n, 0), posRight(n, n - k), sum(n + 1, 0), ans(3, 0); 6 | sum[0] = nums[0]; 7 | for(int i = 1; i <= n; i++) { 8 | sum[i] = sum[i - 1] + nums[i - 1]; 9 | } 10 | for(int i = k, tot = sum[k] - sum[0]; i < n; i++) { 11 | if(sum[i + 1] - sum[i + 1 - k] > tot) { 12 | tot = sum[i + 1] - sum[i + 1 - k]; 13 | posLeft[i] = i + 1 - k; 14 | } 15 | else 16 | posLeft[i] = posLeft[i - 1]; 17 | } 18 | for(int i = n - k - 1, tot = sum[n] - sum[n - k]; i >= 0; i--) { 19 | if(sum[i + k] - sum[i] >= tot) { 20 | tot = sum[i + k] - sum[i]; 21 | posRight[i] = i; 22 | } 23 | else 24 | posRight[i] = posRight[i + 1]; 25 | } 26 | int maxSum = 0; 27 | for(int i = k; i <= n - 2 * k; i++) { 28 | int l = posLeft[i - 1], r = posRight[i + k]; 29 | int tot = (sum[l + k] - sum[l]) + (sum[i + k] - sum[i]) + (sum[r + k] - sum[r]); 30 | if(tot > maxSum) { 31 | maxSum = tot; 32 | ans = { l, i, r }; 33 | } 34 | } 35 | return ans; 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Dynamic-Programming 2 | Dynamic Programming is mainly an optimization over plain recursion. 3 | Wherever we see a recursive solution that has repeated calls for same inputs, we can optimize it using Dynamic Programming. 4 | The idea is to simply store the results of subproblems, so that we do not have to re-compute them when needed later. 5 | This simple optimization reduces time complexities from exponential to polynomial. 6 | Here are some of the questions. 7 | --------------------------------------------------------------------------------