0% found this document useful (0 votes)
2 views13 pages

Rod-Cutting Problem: Maximization Objective, Divisible Input, Overlapping Subproblems, Dynamic Pricing or Resource Management

The document contains various algorithms and their implementations in C++ for solving common computational problems including rod-cutting, longest common subsequence, unique paths in a grid, longest palindromic subsequence, subset sum, longest increasing subsequence, 0-1 knapsack, fractional knapsack, sorting pairs and maps, and binary search. Each algorithm is accompanied by example usage demonstrating its functionality. The document serves as a comprehensive reference for dynamic programming and sorting techniques.

Uploaded by

thewolverine1753
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views13 pages

Rod-Cutting Problem: Maximization Objective, Divisible Input, Overlapping Subproblems, Dynamic Pricing or Resource Management

The document contains various algorithms and their implementations in C++ for solving common computational problems including rod-cutting, longest common subsequence, unique paths in a grid, longest palindromic subsequence, subset sum, longest increasing subsequence, 0-1 knapsack, fractional knapsack, sorting pairs and maps, and binary search. Each algorithm is accompanied by example usage demonstrating its functionality. The document serves as a comprehensive reference for dynamic programming and sorting techniques.

Uploaded by

thewolverine1753
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 13

1.

rod-cutting problem:
Maximization Objective, Divisible Input, Overlapping Subproblems,Dynamic
Pricing or Resource Management
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

// Function to solve the rod cutting problem


int rodCutting(const vector<int>& prices, int n) {
// Create a table to store the maximum profit for each length
vector<int> dp(n + 1, 0);

// Build the table dp[] in a bottom-up manner


for (int i = 1; i <= n; ++i) {
int max_val = INT_MIN; // Initialize max_val to a very small number

// Consider all possible cuts by iterating through the lengths


for (int j = 0; j < i; ++j) {
// Update max_val to the maximum of its current value and
// the sum of the price of the piece of length (j + 1) and
// the maximum profit for the remaining length (i - j - 1)
max_val = max(max_val, prices[j] + dp[i - j - 1]);
}

// Store the maximum profit for rod length i


dp[i] = max_val;
}

return dp[n]; // The maximum profit for rod length n


}

// Example usage
int main() {
vector<int> prices = {1, 5, 8, 9, 10, 17, 17, 20}; // Prices for rods of length 1 to 8
int n = 8; // Total length of the rod
cout << "Maximum profit: " << rodCutting(prices, n) << endl;
return 0;
}

2. LCS
Use LCS to find the longest subsequence common to two strings, preserving
order but not requiring contiguity.
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

// Recursive function to find the length of the Longest Common Subsequence


int lcsRecursive(const string& X, const string& Y, int m, int n) {
// Base case: If either string is empty, the LCS length is 0
if (m == 0 || n == 0)
return 0;

// If the last characters of both strings match, reduce both lengths by 1 and add 1 to
the result
if (X[m - 1] == Y[n - 1])
return 1 + lcsRecursive(X, Y, m - 1, n - 1);

// If the last characters don't match, take the maximum between


// reducing the length of X by 1 or reducing the length of Y by 1
else
return max(lcsRecursive(X, Y, m, n - 1), lcsRecursive(X, Y, m - 1, n));
}

// Example usage
int main() {
string X = "ABCBDAB";
string Y = "BDCAB";
int m = X.size();
int n = Y.size();

cout << "Length of LCS: " << lcsRecursive(X, Y, m, n) << endl;


return 0;
}

3. All possible paths:


"Use this function to count the number of unique paths in a grid from top-left to
bottom-right, moving only down or right."
#include <iostream>
#include <unordered_map>
using namespace std;

// Helper function to create a key for memoization


string makeKey(int m, int n) {
return to_string(m) + "," + to_string(n);
}
// Recursive function to count the number of unique paths with memoization
int countPathsRecursive(int m, int n, unordered_map<string, int>& memo) {
// Base case: If we are at the first row or first column, there is only one path to reach
here
if (m == 1 || n == 1)
return 1;

// Generate a key for the current (m, n)


string key = makeKey(m, n);

// If the result is already computed, return it from the memo dictionary


if (memo.find(key) != memo.end())
return memo[key];

// Calculate the result recursively and store it in memo


memo[key] = countPathsRecursive(m - 1, n, memo) + countPathsRecursive(m, n - 1,
memo);
return memo[key];
}

// Wrapper function to initialize memoization


int countPaths(int m, int n) {
unordered_map<string, int> memo;
return countPathsRecursive(m, n, memo);
}

// Example usage
int main() {
int m = 3, n = 3; // Grid dimensions
cout << "Number of unique paths: " << countPaths(m, n) << endl;
return 0;
}

4. Longest Palindromic Subsequence


"Use this function to find the longest subsequence in a string that reads the same
backward as forward."
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

// Recursive function to find the length of the Longest Palindromic Subsequence


int lpsRecursive(const string& s, int i, int j) {
// Base case: If there is only one character, it's a palindrome of length 1
if (i == j)
return 1;

// If there are only two characters and both are the same, it's a palindrome of length 2
if (s[i] == s[j] && i + 1 == j)
return 2;

// If the first and last characters are the same


if (s[i] == s[j])
return 2 + lpsRecursive(s, i + 1, j - 1);

// If the first and last characters are not the same


return max(lpsRecursive(s, i, j - 1), lpsRecursive(s, i + 1, j));
}

// Example usage
int main() {
string s = "BBABCBCAB";
cout << "Length of Longest Palindromic Subsequence: " << lpsRecursive(s, 0, s.size()
- 1) << endl;
return 0;
}

5. Subset Sum
"Use this function to check if any subset of a set can sum up to a given target
value."
#include <iostream>
#include <vector>
using namespace std;

// Recursive function to determine if a subset with the given target sum exists
bool subsetSumRecursive(const vector<int>& arr, int n, int target) {
// Base Case: If target is 0, we can always achieve it with an empty subset
if (target == 0)
return true;

// Base Case: If no elements are left and target is not 0, it's not achievable
if (n == 0)
return false;

// If the last element is greater than the target, exclude it


if (arr[n - 1] > target)
return subsetSumRecursive(arr, n - 1, target);
// Otherwise, check two possibilities: include or exclude the last element
return subsetSumRecursive(arr, n - 1, target) || subsetSumRecursive(arr, n - 1, target -
arr[n - 1]);
}

// Example usage
int main() {
vector<int> arr = {3, 34, 4, 12, 5, 2};
int target = 9;

if (subsetSumRecursive(arr, arr.size(), target))


cout << "Subset with the given sum exists." << endl;
else
cout << "No subset with the given sum exists." << endl;

return 0;
}

6. Longest Increasing Subsequence


One-Liner for Identification of Usage: "Use this function to find the length of the
longest subsequence of a sequence where the elements are strictly increasing."
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

// Recursive function to find the LIS with memoization


int lisRecursive(const vector<int>& arr, int prev_index, int current_index,
vector<vector<int>>& memo) {
if (current_index == arr.size())
return 0;

if (memo[prev_index + 1][current_index] != -1)


return memo[prev_index + 1][current_index];

// Case 1: Exclude the current element and move to the next


int exclude = lisRecursive(arr, prev_index, current_index + 1, memo);

// Case 2: Include the current element if it's larger than the previous element in the
sequence
int include = 0;
if (prev_index == -1 || arr[current_index] > arr[prev_index])
include = 1 + lisRecursive(arr, current_index, current_index + 1, memo);
memo[prev_index + 1][current_index] = max(exclude, include);
return memo[prev_index + 1][current_index];
}

// Wrapper function for LIS


int lis(const vector<int>& arr) {
int n = arr.size();
vector<vector<int>> memo(n + 1, vector<int>(n, -1)); // Initialize memo table
return lisRecursive(arr, -1, 0, memo);
}

// Example usage
int main() {
vector<int> arr = {10, 22, 9, 33, 21, 50, 41, 60};
cout << "Length of LIS: " << lis(arr) << endl;
return 0;
}

7. 0-1 Knapsack
One-Liner for Identification of Usage: "Use this function to maximize the total
value of items that can be included in a knapsack of limited capacity without
breaking items."
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

// Function to solve 0-1 Knapsack problem with memoization


int knapsackMemoized(const vector<int>& values, const vector<int>& weights, int W, int
n, vector<vector<int>>& memo) {
// Base Case: If no items left or capacity is 0, the maximum value is 0
if (n == 0 || W == 0)
return 0;

// If result is already computed, return it


if (memo[n][W] != -1)
return memo[n][W];

// If the weight of the nth item is more than the capacity W, it cannot be included
if (weights[n - 1] > W)
memo[n][W] = knapsackMemoized(values, weights, W, n - 1, memo);
else
// Otherwise, check the maximum value of two cases:
// 1. Including the nth item
// 2. Excluding the nth item
memo[n][W] = max(
values[n - 1] + knapsackMemoized(values, weights, W - weights[n - 1], n - 1,
memo),
knapsackMemoized(values, weights, W, n - 1, memo)
);

return memo[n][W];
}

// Example usage
int main() {
vector<int> values = {60, 100, 120};
vector<int> weights = {10, 20, 30};
int W = 50; // Knapsack capacity
int n = values.size();
vector<vector<int>> memo(n + 1, vector<int>(W + 1, -1)); // Initialize memo table

cout << "Maximum value in Knapsack: " << knapsackMemoized(values, weights, W, n,


memo) << endl;
return 0;
}

8. Fractional Knapsack
One-Liner for Identification of Usage: "Use this function to maximize the total
value of items that can be included in a knapsack, allowing fractional items.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

// Structure to represent an item


struct Item {
int value, weight;
double ratio;
};

// Comparison function to sort items by value-to-weight ratio in descending order


bool compare(Item a, Item b) {
return a.ratio > b.ratio;
}
// Function to solve Fractional Knapsack problem
double fractionalKnapsack(int capacity, const vector<int>& values, const vector<int>&
weights) {
vector<Item> items;
for (size_t i = 0; i < values.size(); ++i) {
items.push_back({values[i], weights[i], (double)values[i] / weights[i]});
}

// Sort items by value-to-weight ratio


sort(items.begin(), items.end(), compare);

double totalValue = 0.0; // Total value of the knapsack

for (auto& item : items) {


if (capacity >= item.weight) {
// Add the entire item
capacity -= item.weight;
totalValue += item.value;
} else {
// Add a fraction of the item
totalValue += item.value * ((double)capacity / item.weight);
break;
}
}

return totalValue;
}

// Example usage
int main() {
vector<int> values = {60, 100, 120};
vector<int> weights = {10, 20, 30};
int capacity = 50;

cout << "Maximum value in Fractional Knapsack: " << fractionalKnapsack(capacity,


values, weights) << endl;
return 0;
}

9. Sorting on 2nd Element, then 1st Element

One-Liner for Identification of Usage: "Use this function to sort a vector of pairs by the
second element, breaking ties with the first element."
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

// Comparator function to sort by second element, then by first element


bool sortBySecondThenFirst(const pair<int, int>& a, const pair<int, int>& b) {
if (a.second == b.second)
return a.first < b.first;
return a.second < b.second;
}

// Example usage
int main() {
vector<pair<int, int>> arr = {{3, 2}, {1, 3}, {1, 2}, {3, 3}, {2, 2}};
sort(arr.begin(), arr.end(), sortBySecondThenFirst);

cout << "Sorted array:" << endl;


for (const auto& p : arr)
cout << "(" << p.first << ", " << p.second << ")" << endl;

return 0;
}

10. Sorting a Map by Values


One-Liner for Identification of Usage: "Use this function to sort a map by its
values while keeping keys intact."
#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;

// Comparator function to sort map by values


bool sortByValue(const pair<string, int>& a, const pair<string, int>& b) {
return a.second < b.second;
}

// Example usage
int main() {
map<string, int> myDict = {{"apple", 10}, {"banana", 5}, {"cherry", 15}};
vector<pair<string, int>> sortedDict(myDict.begin(), myDict.end());
// Sort by value
sort(sortedDict.begin(), sortedDict.end(), sortByValue);

cout << "Sorted dictionary (ascending):" << endl;


for (const auto& p : sortedDict)
cout << p.first << ": " << p.second << endl;

return 0;
}

11. Binary Search


One-Liner for Identification of Usage: "Use this function to search for an element
in a sorted array in O(log n) time."
#include <iostream>
#include <vector>
using namespace std;

// Function for Binary Search


int binarySearch(const vector<int>& arr, int x) {
int left = 0, right = arr.size() - 1;

while (left <= right) {


int mid = left + (right - left) / 2;

if (arr[mid] == x)
return mid;
else if (arr[mid] < x)
left = mid + 1;
else
right = mid - 1;
}

return -1; // Element not found


}

// Example usage
int main() {
vector<int> arr = {1, 3, 5, 7, 9};
int x = 5;

int result = binarySearch(arr, x);


if (result != -1)
cout << "Element found at index: " << result << endl;
else
cout << "Element not found." << endl;

return 0;
}

12. Vectors:
#include <vector>
std::vector<int> vec; // Declares a vector of integers
std::vector<int> vec(5); // Declares a vector of size 5 with default values (0 for int)
std::vector<int> vec(5, 10); // Declares a vector of size 5 initialized with 10
std::vector<int> vec = {1, 2, 3}; // Declares and initializes a vector

12.
#include <stack>
std::stack<int> s;
#include <queue>
std::queue<int> q;

#include <list>
std::list<int> lst;
DATA STRUCTURES:

You might also like