0% found this document useful (0 votes)
3 views22 pages

Sample Dynamic Programming

Dynamic Programming (DP) is an algorithmic technique that solves optimization problems by breaking them into simpler sub-problems and storing results to avoid redundant calculations. Key concepts include optimal substructure and overlapping sub-problems, with approaches like Top-Down (Memoization) and Bottom-Up (Tabulation). The document provides examples of various DP problems such as Fibonacci Sequence, Longest Increasing Subsequence, Knapsack Problem, and more, along with their implementations.

Uploaded by

Parineeta Deb
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)
3 views22 pages

Sample Dynamic Programming

Dynamic Programming (DP) is an algorithmic technique that solves optimization problems by breaking them into simpler sub-problems and storing results to avoid redundant calculations. Key concepts include optimal substructure and overlapping sub-problems, with approaches like Top-Down (Memoization) and Bottom-Up (Tabulation). The document provides examples of various DP problems such as Fibonacci Sequence, Longest Increasing Subsequence, Knapsack Problem, and more, along with their implementations.

Uploaded by

Parineeta Deb
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

Dynamic Programming

Dynamic Programming (DP) is an algorithmic technique used to solve optimization


problems by breaking them down into simpler sub-problems and solving each sub-
problem just once, storing the results for future use. This approach avoids redundant
calculations and significantly reduces the computation time for problems with
overlapping sub-problems and optimal substructure properties.

Key Concepts of Dynamic Programming:

1. Optimal Substructure: The optimal solu\tion to the problem can be constructed from optimal
solutions of its sub-problems.
2. Overlapping Sub-problems: The problem can be broken down into sub-problems that are
reused multiple times.

Types of Dynamic Programming Approaches:

1. Top-Down (Memoization): Recursively break down the problem and store the results of sub-
problems in a table (array, hashmap) to avoid recomputation.
2. Bottom-Up (Tabulation): Iteratively solve all sub-problems and store their results in a table,
building up the solution from the simplest sub-problems.

1. Fibonacci Sequence

#include <stdio.h>
int fibonacci(int n) {
int dp[n+1];
dp[0] = 0;
dp[1] = 1;

for (int i = 2; i <= n; i++) {


dp[i] = dp[i-1] + dp[i-2];
}
return dp[n];
}
int main() {
int n = 10; // Example
printf("Fibonacci number at position %d is %d\n", n,
fibonacci(n));
return 0;
}
2. Longest Increasing Subsequence

Given an array of integers, find the length of the longest increasing subsequence.

Example

Consider the array arr = [10, 22, 9, 33, 21, 50, 41, 60, 80].

The longest increasing subsequence is [10, 22, 33, 50, 60, 80], and its length is
6.

#include <stdio.h>
int lis(int arr[], int n) {
int lis[n];
for (int i = 0; i < n; i++) lis[i] = 1;

for (int i = 1; i < n; i++) {


for (int j = 0; j < i; j++) {
if (arr[i] > arr[j] && lis[i] < lis[j] + 1) {
lis[i] = lis[j] + 1;
}
}
}

int max = 0;
for (int i = 0; i < n; i++) {
if (max < lis[i]) {
max = lis[i];
}
}
return max;
}
int main() {
int arr[] = {10, 22, 9, 33, 21, 50, 41, 60, 80};
int n = sizeof(arr)/sizeof(arr[0]);
printf("Length of LIS is %d\n", lis(arr, n));
return 0;
}

3. Knapsack Problem

Given a set of items, each with a weight and a value, determine the number of each
item to include in a collection so that the total weight does not exceed a given limit
and the total value is as large as possible. Each item can either be taken or not taken
(hence the name 0/1).
Example: Consider a knapsack with a weight capacity of W = 50 and the following
items:

Item Weight Value


1 10 60
2 20 100
3 30 120

The goal is to maximize the value without exceeding the weight capacity.

#include <stdio.h>
int max(int a, int b) { return (a > b) ? a : b; }
int knapSack(int W, int wt[], int val[], int n) {
int dp[n+1][W+1];

for (int i = 0; i <= n; i++) {


for (int w = 0; w <= W; w++) {
if (i == 0 || w == 0)
dp[i][w] = 0;
else if (wt[i-1] <= w)
dp[i][w] = max(val[i-1] + dp[i-1][w-wt[i-1]], dp[i-
1][w]);
else
dp[i][w] = dp[i-1][w];
}
}
return dp[n][W];
}
int main() {
int val[] = {60, 100, 120};
int wt[] = {10, 20, 30};
int W = 50;
int n = sizeof(val) / sizeof(val[0]);
printf("Maximum value in Knapsack = %d\n", knapSack(W, wt, val,
n));
return 0;
}

4. Coin Change Problem

Given a set of m coin denominations {c1, c2, ..., cm} and a target amount V, find
the minimum number of coins needed to make the amount V. If it is not possible to
make the amount with the given coin denominations, return -1.
Approach:

 Use dynamic programming to build a solution.


 Create an array dp where dp[i] represents the minimum number of coins needed to make
the amount i.
 Initialize dp[0] to 0 because no coins are needed to make the amount 0.
 Initialize all other entries of dp to a value greater than the maximum possible (e.g.,
INT_MAX).
 For each coin, update the dp array by checking if using the coin results in a smaller number
of coins than the current value.

#include <stdio.h>
#include <limits.h>
int minCoins(int coins[], int m, int V) {
int dp[V+1];
dp[0] = 0;

for (int i = 1; i <= V; i++) {


dp[i] = INT_MAX;
}

for (int i = 1; i <= V; i++) {


for (int j = 0; j < m; j++) {
if (coins[j] <= i) {
int sub_res = dp[i - coins[j]];
if (sub_res != INT_MAX && sub_res + 1 < dp[i]) {
dp[i] = sub_res + 1;
}
}
}
}
return dp[V];
}
int main() {
int coins[] = {1, 2, 5};
int m = sizeof(coins)/sizeof(coins[0]);
int V = 11;
printf("Minimum coins required is %d\n", minCoins(coins, m, V));
return 0;
}

5. Edit Distance

Given two strings, str1 and str2, find the minimum number of operations required
to convert str1 into str2.
Example

Consider the strings str1 = "kitten" and str2 = "sitting".

The edit distance between them is 3, with the following operations:

1. Substitute 'k' with 's' (kitten -> sitten)


2. Substitute 'e' with 'i' (sitten -> sittin)
3. Insert 'g' at the end (sittin -> sitting)

#include <stdio.h>
#include <string.h>
int min(int x, int y, int z) {
return x < y ? (x < z ? x : z) : (y < z ? y : z);
}
int editDistance(char str1[], char str2[], int m, int n) {
int dp[m+1][n+1];

for (int i = 0; i <= m; i++) {


for (int j = 0; j <= n; j++) {
if (i == 0)
dp[i][j] = j;
else if (j == 0)
dp[i][j] = i;
else if (str1[i-1] == str2[j-1])
dp[i][j] = dp[i-1][j-1];
else
dp[i][j] = 1 + min(dp[i][j-1], dp[i-1][j], dp[i-1][j-
1]);
}
}
return dp[m][n];
}
int main() {
char str1[] = "sunday";
char str2[] = "saturday";
printf("Edit Distance = %d\n", editDistance(str1, str2,
strlen(str1), strlen(str2)));
return 0;
}

5. Longest Common Subsequence


Given two sequences (strings), find the length of their longest common subsequence.
A subsequence is a sequence derived by deleting some or no elements of the sequence
without changing the order of the remaining elements.

Example

Consider the strings str1 = "ABCBDAB" and str2 = "BDCAB".

The longest common subsequence is "BCAB", and its length is 4.

#include <stdio.h>
#include <string.h>
int max(int a, int b) { return (a > b) ? a : b; }
int lcs(char* X, char* Y, int m, int n) {
int dp[m+1][n+1];

for (int i = 0; i <= m; i++) {


for (int j = 0; j <= n; j++) {
if (i == 0 || j == 0)
dp[i][j] = 0;
else if (X[i-1] == Y[j-1])
dp[i][j] = dp[i-1][j-1] + 1;
else
dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
}
}
return dp[m][n];
}
int main() {
char X[] = "AGGTAB";
char Y[] = "GXTXAYB";
int m = strlen(X);
int n = strlen(Y);
printf("Length of LCS is %d\n", lcs(X, Y, m, n));
return 0;
}

7. 0/1 Knapsack Problem with Space Optimization

Given a set of items, each with a weight and a value, determine the number of each
item to include in a collection so that the total weight is less than or equal to a given
limit and the total value is as large as possible. Each item can either be included in the
collection or not (hence the name 0/1).

Problem Statement
Given:

 n items, each with a weight w[i] and a value v[i].


 A knapsack with a maximum capacity W.

Find the maximum value that can be achieved by selecting a subset of the items such
that their total weight does not exceed W.

Example

Consider the following items and knapsack capacity:

Items:

 Item 1: weight = 2, value = 3


 Item 2: weight = 3, value = 4
 Item 3: weight = 4, value = 5
 Item 4: weight = 5, value = 8

Knapsack capacity: W = 5

The maximum value that can be achieved is 8 by selecting item 4.

#include <stdio.h>
int max(int a, int b) { return (a > b) ? a : b; }
int knapSack(int W, int wt[], int val[], int n) {
int dp[W+1];
for (int i = 0; i <= W; i++) dp[i] = 0;

for (int i = 0; i < n; i++) {


for (int w = W; w >= wt[i]; w--) {
dp[w] = max(dp[w], dp[w - wt[i]] + val[i]);
}
}
return dp[W];
}
int main() {
int val[] = {60, 100, 120};
int wt[] = {10, 20, 30};
int W = 50;
int n = sizeof(val) / sizeof(val[0]);
printf("Maximum value in Knapsack = %d\n", knapSack(W, wt, val,
n));
return 0;
}
8. Subset Sum Problem

Given a set of n integers and a target sum S, determine if there is a subset of the given
set with a sum equal to S.

Example

Consider the set arr = {3, 34, 4, 12, 5, 2} and target sum S = 9.

The subset {4, 5} sums to 9, so the answer is true.

#include <stdio.h>
#include <stdbool.h>
bool isSubsetSum(int set[], int n, int sum) {
bool dp[sum+1];
for (int i = 0; i <= sum; i++) dp[i] = false;

dp[0] = true;

for (int i = 0; i < n; i++) {


for (int j = sum; j >= set[i]; j--) {
if (dp[j - set[i]]) {
dp[j] = true;
}
}
}
return dp[sum];
}
int main() {
int set[] = {3, 34, 4, 12, 5, 2};
int sum = 9;
int n = sizeof(set)/sizeof(set[0]);
if (isSubsetSum(set, n, sum))
printf("Found a subset with given sum\n");
else
printf("No subset with given sum\n");
return 0;
}

9. Matrix Chain Multiplication

Given a sequence of matrices A1,A2,…,AnA1​ ,A2​ ,…,An​ where AiAi​ has


dimensions pi−1×pipi−1​ ×pi​ , the task is to find the most efficient way to multiply
these matrices together. The order in which the matrices are multiplied can
significantly affect the number of operations required.
Example

Consider the matrices with dimensions:

 A1A1​ : 10×3010×30
 A2A2​ : 30×530×5
 A3A3​ : 5×605×60

The optimal way to multiply these matrices together to minimize the number of scalar
multiplications can be different from simply multiplying them in the given order.

#include <stdio.h>
#include <limits.h>
int matrixChainOrder(int p[], int n) {
int dp[n][n];
for (int i = 1; i < n; i++) dp[i][i] = 0;

for (int L = 2; L < n; L++) {


for (int i = 1; i < n - L + 1; i++) {
int j = i + L - 1;
dp[i][j] = INT_MAX;
for (int k = i; k <= j - 1; k++) {
int q = dp[i][k] + dp[k+1][j] + p[i-1]*p[k]*p[j];
if (q < dp[i][j])
dp[i][j] = q;
}
}
}
return dp[1][n-1];
}
int main() {
int arr[] = {1, 2, 3, 4};
int n = sizeof(arr)/sizeof(arr[0]);
printf("Minimum number of multiplications is %d\n",
matrixChainOrder(arr, n));
return 0;
}

10. Minimum Cost Path

Given a grid (2D array) of size m x n where each cell contains a non-negative integer
representing the cost to traverse that cell, find the minimum cost path from the top-left
corner (cell [0][0]) to the bottom-right corner (cell [m-1][n-1]).

Example
Consider the following cost matrix:

1 3 1
1 5 1
4 2 1

The minimum cost path from the top-left corner to the bottom-right corner is 1 -> 3
-> 1 -> 1 -> 1, which has a total cost of 7.

#include <stdio.h>
#include <limits.h>
#define R 3
#define C 3
int min(int x, int y, int z) {
return x < y ? (x < z ? x : z) : (y < z ? y : z);
}
int minCost(int cost[R][C], int m, int n) {
int dp[R][C];
dp[0][0] = cost[0][0];

for (int i = 1; i <= m; i++)


dp[i][0] = dp[i-1][0] + cost[i][0];

for (int j = 1; j <= n; j++)


dp[0][j] = dp[0][j-1] + cost[0][j];

for (int i = 1; i <= m; i++) {


for (int j = 1; j <= n; j++) {
dp[i][j] = cost[i][j] + min(dp[i-1][j-1], dp[i-1][j],
dp[i][j-1]);
}
}
return dp[m][n];
}
int main() {
int cost[R][C] = { {1, 2, 3},
{4, 8, 2},
{1, 5, 3} };
printf("Minimum cost to reach (2, 2) is %d\n", minCost(cost, 2,
2));
return 0;
}

11. Maximum Sum Subarray (Kadane's Algorithm)


Kadane's Algorithm is a popular and efficient method used to find the maximum sum
of a contiguous subarray within a one-dimensional array of numbers. This algorithm
runs in linear time, making it very efficient for this type of problem.

Problem Statement

Given an array of integers, find the contiguous subarray (containing at least one
number) which has the largest sum and return its sum.

Example

Consider the array:

css
[-2, 1, -3, 4, -1, 2, 1, -5, 4]

The contiguous subarray with the maximum sum is [4, -1, 2, 1], which has a sum
of 6.

Kadane's Algorithm

Kadane's Algorithm maintains a running maximum sum of the subarray ending at the
current position and updates the overall maximum sum found so far.

Steps:

Initialization:

1. Initialize two variables:


1. max_current to keep track of the maximum sum of the subarray ending
at the current position.
2. max_global to keep track of the maximum sum found so far.
2. Set both max_current and max_global to the first element of the array.

Iterate Through the Array:

1. For each element in the array (starting from the second element), update
max_current to be the maximum of the current element itself or the current
element plus max_current. This step decides whether to add the current
element to the existing subarray or to start a new subarray from the current
element.
2. Update max_global to be the maximum of max_global and max_current.

Result:

1. After iterating through the array, max_global will contain the maximum sum of
the contiguous subarray.

#include <stdio.h>
#include <limits.h>
int maxSubArraySum(int arr[], int size) {
int max_so_far = INT_MIN, max_ending_here = 0;

for (int i = 0; i < size; i++) {


max_ending_here = max_ending_here + arr[i];
if (max_so_far < max_ending_here)
max_so_far = max_ending_here;
if (max_ending_here < 0)
max_ending_here = 0;
}
return max_so_far;
}
int main() {
int arr[] = {-2, -3, 4, -1, -2, 1, 5, -3};
int n = sizeof(arr)/sizeof(arr[0]);
printf("Maximum contiguous sum is %d\n", maxSubArraySum(arr, n));
return 0;
}

12. Minimum Number of Coins for Change (Unbounded Knapsack


Variation)

The Minimum Number of Coins for Change problem is a variation of the classic
Unbounded Knapsack problem. In this problem, given a target amount and a set of
coin denominations, the goal is to find the minimum number of coins needed to make
the target amount.

Problem Statement

Given an integer amount representing the target amount of money and an array coins
representing the denominations of coins available, find the minimum number of coins
needed to make the amount. You can assume that there is an infinite supply of each
coin denomination.

Example

Consider the following example:

 amount = 11
 coins = [1, 2, 5]

To make the amount 11, we can use the following combinations:

 11 = 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1, using 11 coins of
denomination 1.
 11 = 5 + 5 + 1, using 3 coins (2 of denomination 5 and 1 of denomination 1).
 11 = 5 + 2 + 2 + 2, using 4 coins (1 of denomination 5 and 3 of denomination 2).

The minimum number of coins needed is 3.

#include <stdio.h>
#include <limits.h>
int minCoins(int coins[], int m, int V) {
int dp[V+1];
for (int i = 0; i <= V; i++) dp[i] = INT_MAX;
dp[0] = 0;

for (int i = 1; i <= V; i++) {


for (int j = 0; j < m; j++) {
if (coins[j] <= i) {
int sub_res = dp[i - coins[j]];
if (sub_res != INT_MAX && sub_res + 1 < dp[i])
dp[i] = sub_res + 1;
}
}
}
return dp[V];
}
int main() {
int coins[] = {1, 2, 3};
int m = sizeof(coins)/sizeof(coins[0]);
int V = 5;
printf("Minimum coins required is %d\n", minCoins(coins, m, V));
return 0;
}

13. Longest Palindromic Subsequence

A Longest Palindromic Subsequence (LPS) is a sequence of characters that reads the


same forwards and backwards. The problem of finding the Longest Palindromic
Subsequence in a given string is a classic problem in computer science and dynamic
programming.

Problem Statement

Given a string s, find the length of the Longest Palindromic Subsequence (LPS) in s.

Example

Consider the string s = "bbbab".


A possible Longest Palindromic Subsequence is "bbbb", which has a length of 4.

#include <stdio.h>
#include <string.h>
int max(int a, int b) { return (a > b) ? a : b; }
int lps(char* seq, int i, int j) {
if (i == j)
return 1;
if (seq[i] == seq[j] && i + 1 == j)
return 2;
if (seq[i] == seq[j])
return lps(seq, i + 1, j - 1) + 2;
return max(lps(seq, i, j - 1), lps(seq, i + 1, j));
}
int main() {
char seq[] = "KIIT UNIVERSITY";
int n = strlen(seq);
printf("The length of the LPS is %d\n", lps(seq, 0, n - 1));
return 0;
}

14. Egg Dropping Puzzle

Given nn eggs and a building with mm floors, determine the minimum


number of attempts needed to find the highest floor from which an egg
can be dropped without breaking. You are provided with an unlimited
number of eggs and can use them in any way you want.

#include <stdio.h>
#include <limits.h>
int max(int a, int b) { return (a > b) ? a : b; }
int eggDrop(int n, int k) {
int dp[n+1][k+1];
int res;
for (int i = 1; i <= n; i++) {
dp[i][1] = 1;
dp[i][0] = 0;
}

for (int j = 1; j <= k; j++)


dp[1][j] = j;

for (int i = 2; i <= n; i++) {


for (int j = 2; j <= k; j++) {
dp[i][j] = INT_MAX;
for (int x = 1; x <= j; x++) {
res = 1 + max(dp[i-1][x-1], dp[i][j-x]);
if (res < dp[i][j])
dp[i][j] = res;
}
}
}
return dp[n][k];
}
int main() {
int n = 2, k = 10;
printf("Minimum number of trials in worst case with %d eggs
and %d floors is %d\n", n, k, eggDrop(n, k));
return 0;
}

15. Maximum Size Square Sub-matrix with All 1s

Given a binary matrix where each cell contains either a 0 or a 1, the


goal is to find the largest square sub-matrix containing only 1s and
return its side length.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define R 6
#define C 5
int min(int a, int b, int c) {
int m = a;
if (m > b) m = b;
if (m > c) m = c;
return m;
}
void printMaxSubSquare(int M[R][C]) {
int i, j;
int S[R][C];
int max_of_s, max_i, max_j;

for (i = 0; i < R; i++)


S[i][0] = M[i][0];

for (j = 0; j < C; j++)


S[0][j] = M[0][j];
for (i = 1; i < R; i++) {
for (j = 1; j < C; j++) {
if (M[i][j] == 1)
S[i][j] = min(S[i][j-1], S[i-1][j], S[i-1][j-1]) + 1;
else
S[i][j] = 0;
}
}

max_of_s = S[0][0]; max_i = 0; max_j = 0;


for (i = 0; i < R; i++) {
for (j = 0; j < C; j++) {
if (max_of_s < S[i][j]) {
max_of_s = S[i][j];
max_i = i;
max_j = j;
}
}
}

printf("Maximum size sub-matrix is: \n");


for (i = max_i; i > max_i - max_of_s; i--) {
for (j = max_j; j > max_j - max_of_s; j--) {
printf("%d ", M[i][j]);
}
printf("\n");
}
}
int main() {
int M[R][C] = { {0, 1, 1, 0, 1},
{1, 1, 0, 1, 0},
{0, 1, 1, 1, 0},
{1, 1, 1, 1, 0},
{1, 1, 1, 1, 1},
{0, 0, 0, 0, 0} };
printMaxSubSquare(M);
return 0;
}

16. Longest Palindromic Substring

Given a string, the goal is to find the longest substring that is a


palindrome.
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
void printSubStr(char* str, int low, int high) {
for (int i = low; i <= high; ++i)
printf("%c", str[i]);
}
int longestPalSubstr(char* str) {
int n = strlen(str);
bool table[n][n];
memset(table, 0, sizeof(table));

int maxLength = 1;
for (int i = 0; i < n; ++i)
table[i][i] = true;

int start = 0;
for (int i = 0; i < n - 1; ++i) {
if (str[i] == str[i + 1]) {
table[i][i + 1] = true;
start = i;
maxLength = 2;
}
}

for (int k = 3; k <= n; ++k) {


for (int i = 0; i < n - k + 1; ++i) {
int j = i + k - 1;
if (table[i][j - 1] && str[i] == str[j]) {
table[i][j] = true;
if (k > maxLength) {
start = i;
maxLength = k;
}
}
}
}

printf("Longest palindrome substring is: ");


printSubStr(str, start, start + maxLength - 1);

return maxLength;
}
int main() {
char str[] = "kiitiit";
printf("\nLength is: %d\n", longestPalSubstr(str));
return 0;
}

17. Count of Subsets with a Given Sum.

Given an array arr[] of integers and a target sum target, find the
number of subsets of arr[] whose elements sum up to target.

#include <stdio.h>
int countSubsets(int arr[], int n, int sum) {
int dp[n+1][sum+1];

for (int i = 0; i <= n; i++)


dp[i][0] = 1;

for (int i = 1; i <= sum; i++)


dp[0][i] = 0;

for (int i = 1; i <= n; i++) {


for (int j = 1; j <= sum; j++) {
if (arr[i-1] <= j)
dp[i][j] = dp[i-1][j] + dp[i-1][j-arr[i-1]];
else
dp[i][j] = dp[i-1][j];
}
}

return dp[n][sum];
}
int main() {
int arr[] = {2, 3, 5, 6, 8, 10};
int sum = 10;
int n = sizeof(arr)/sizeof(arr[0]);
printf("Count of subsets with given sum is %d\n",
countSubsets(arr, n, sum));
return 0;
}

18. Boolean Parenthesization Problem


Given a boolean expression expr[] consisting of boolean variables
(true and false) and boolean operators (&, |, and ^), and a desired
boolean result result, find the number of ways to parenthesize the
expression such that it evaluates to the desired result.

#include <stdio.h>
#include <string.h>
int countWays(int N, char* S) {
int dpTrue[N][N], dpFalse[N][N];
memset(dpTrue, 0, sizeof(dpTrue));
memset(dpFalse, 0, sizeof(dpFalse));

for (int i = 0; i < N; i += 2) {


dpTrue[i][i] = S[i] == 'T' ? 1 : 0;
dpFalse[i][i] = S[i] == 'F' ? 1 : 0;
}

for (int length = 3; length <= N; length += 2) {


for (int i = 0; i <= N - length; i += 2) {
int j = i + length - 1;
dpTrue[i][j] = dpFalse[i][j] = 0;

for (int k = i + 1; k < j; k += 2) {


int leftT = dpTrue[i][k-1];
int leftF = dpFalse[i][k-1];
int rightT = dpTrue[k+1][j];
int rightF = dpFalse[k+1][j];

if (S[k] == '&') {
dpTrue[i][j] += leftT * rightT;
dpFalse[i][j] += leftT * rightF + leftF * rightT
+ leftF * rightF;
}
else if (S[k] == '|') {
dpFalse[i][j] += leftF * rightF;
dpTrue[i][j] += leftT * rightT + leftT * rightF +
leftF * rightT;
}
else if (S[k] == '^') {
dpTrue[i][j] += leftT * rightF + leftF * rightT;
dpFalse[i][j] += leftT * rightT + leftF * rightF;
}
}
}
}

return dpTrue[0][N-1];
}
int main() {
char symbols[] = "T|F&T^T";
int N = strlen(symbols);
printf("Number of ways to parenthesize the expression to get true
is %d\n", countWays(N, symbols));
return 0;
}

19. Rod Cutting Problem

Given a rod of length nn and a list of prices pipi​ for rods of


length ii (where ii ranges from 1 to nn), the goal is to determine
the maximum revenue that can be obtained by cutting and selling the
rod into smaller pieces.

#include <stdio.h>
int max(int a, int b) { return (a > b) ? a : b; }
int cutRod(int price[], int n) {
int dp[n+1];
dp[0] = 0;

for (int i = 1; i <= n; i++) {


int max_val = -1;
for (int j = 0; j < i; j++)
max_val = max(max_val, price[j] + dp[i-j-1]);
dp[i] = max_val;
}
return dp[n];
}
int main() {
int arr[] = {1, 5, 8, 9, 10, 17, 17, 20};
int size = sizeof(arr)/sizeof(arr[0]);
printf("Maximum Obtainable Value is %d\n", cutRod(arr, size));
return 0;
}

20. Largest Sum Contiguous Subarray (Modified Kadane's


Algorithm for Handling All Negative Values)
The Largest Sum Contiguous Subarray problem, often solved using Kadane's
Algorithm, involves finding the maximum sum of a contiguous subarray within an
array of integers.

However, when all the numbers in the array are negative, Kadane's algorithm may
return 0 (indicating an empty subarray), which may not be the desired behavior. To
handle this scenario, we can modify Kadane's Algorithm to return the maximum
element in the array when all the elements are negative.

Problem Statement

Given an array of integers, find the contiguous subarray with the largest sum.

Modified Kadane's Algorithm

Here's how we can modify Kadane's Algorithm to handle the case when all elements
are negative:

Initialization:

1. Initialize two variables: max_so_far and max_ending_here to store the


maximum sum found so far and the maximum sum ending at the current position,
respectively.
2. Initialize max_elem to store the maximum element in the array.

Traverse the Array:

1. For each element in the array:

 Update max_ending_here as the maximum of the current element and


the sum of the current element and max_ending_here.
 Update max_so_far as the maximum of max_so_far and
max_ending_here.
 Update max_elem as the maximum of max_elem and the current
element.

Result:

1. If max_so_far is greater than 0, return max_so_far.


2. If max_so_far is 0 (indicating that all elements are negative), return max_elem.

#include <stdio.h>
#include <limits.h>
int maxSubArraySum(int arr[], int size) {
int max_so_far = INT_MIN, max_ending_here = 0;

for (int i = 0; i < size; i++) {


max_ending_here = max_ending_here + arr[i];
if (max_ending_here > max_so_far)
max_so_far = max_ending_here;
if (max_ending_here < 0)
max_ending_here = 0;
}

if (max_so_far == INT_MIN) {
max_so_far = arr[0];
for (int i = 1; i < size; i++) {
if (arr[i] > max_so_far)
max_so_far = arr[i];
}
}

return max_so_far;
}
int main() {
int arr[] = {-2, -3, -1, -5, -6};
int n = sizeof(arr)/sizeof(arr[0]);
printf("Maximum contiguous sum is %d\n", maxSubArraySum(arr, n));
return 0;
}

You might also like