Skip to content
geeksforgeeks
  • Courses
    • DSA to Development
    • Get IBM Certification
    • Newly Launched!
      • Master Django Framework
      • Become AWS Certified
    • For Working Professionals
      • Interview 101: DSA & System Design
      • Data Science Training Program
      • JAVA Backend Development (Live)
      • DevOps Engineering (LIVE)
      • Data Structures & Algorithms in Python
    • For Students
      • Placement Preparation Course
      • Data Science (Live)
      • Data Structure & Algorithm-Self Paced (C++/JAVA)
      • Master Competitive Programming (Live)
      • Full Stack Development with React & Node JS (Live)
    • Full Stack Development
    • Data Science Program
    • All Courses
  • Tutorials
    • Data Structures & Algorithms
    • ML & Data Science
    • Interview Corner
    • Programming Languages
    • Web Development
    • CS Subjects
    • DevOps And Linux
    • School Learning
  • Practice
    • Build your AI Agent
    • GfG 160
    • Problem of the Day
    • Practice Coding Problems
    • GfG SDE Sheet
  • Contests
    • Accenture Hackathon (Ending Soon!)
    • GfG Weekly [Rated Contest]
    • Job-A-Thon Hiring Challenge
    • All Contests and Events
  • DSA
  • Interview Problems on DP
  • Practice DP
  • MCQs on DP
  • Tutorial on Dynamic Programming
  • Optimal Substructure
  • Overlapping Subproblem
  • Memoization
  • Tabulation
  • Tabulation vs Memoization
  • 0/1 Knapsack
  • Unbounded Knapsack
  • Subset Sum
  • LCS
  • LIS
  • Coin Change
  • Word Break
  • Egg Dropping Puzzle
  • Matrix Chain Multiplication
  • Palindrome Partitioning
  • DP on Arrays
  • DP with Bitmasking
  • Digit DP
  • DP on Trees
  • DP on Graph
Open In App
Next Article:
Check for balanced parenthesis without using stack
Next article icon

Boolean Parenthesization Problem

Last Updated : 24 Mar, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report
Try it on GfG Practice
redirect icon

Given a boolean expression s that contain symbols and operators. The task is to count the number of ways we can parenthesize the expression so that the value of the expression evaluates to true. 

Symbols

  • T —> true
  • F —> false

Operators

  • & —> boolean AND
  • | —> boolean OR
  • ^ —> boolean XOR

Examples: 

Input: s = T|T&F^T
Output: 4
Explanation: The expression evaluates to true in 4 ways ((T|T)&(F^T)), (T|(T&(F^T))), (((T|T)&F)^T) and (T|((T&F)^T)).

Input: s = T^F|F
Output: 2
Explanation: ((T^F)|F) and (T^(F|F)) are the only ways.

Important Point:

When calculating ways to make an expression evaluate to true, we also need to consider combinations where subexpressions evaluate to false because operators like XOR can produce true when one operand is false. For example, if we have “F^T”, even though the left subexpression evaluates to false, the XOR operation with true on the right gives us true as the final result. Therefore, we need to keep track of both true and false counts for subexpressions to handle all possible combinations correctly. 

Table of Content

  • [Naive Approach] – Using Recursion – O(2^n) Time and O(n^2) Space
  • [Expected Approach 1]- Using Top-Down DP – O(n^3) Time and O(n^2) Space
  • [Expected Approach 2]- Using Bottom-Up DP – O(n^3) Time and O(n^2) Space

[Naive Approach] – Using Recursion – O(2^n) Time and O(n^2) Space

The idea is to solve this recursively by splitting the expression at each operator and evaluating all possible combinations of true/false values from the left and right subexpressions. For each operator position k, we parenthesize the expression into two parts: (i, k-1) and (k+1, j). We then recursively calculate how many ways each part can evaluate to true and false. Once we have these counts, we can combine them based on the operator at position k.

C++
#include <bits/stdc++.h> using namespace std;  // Function to evaluate a // boolean condition. bool evaluate(bool b1, bool b2, char op) {     if (op == '&')     {         return b1 & b2;     }     else if (op == '|')     {         return b1 | b2;     }     return b1 ^ b2; }  // Function which returns the number of ways // s[i:j] evaluates to req. int countRecur(int i, int j, bool req, string &s) {      // Base case:     if (i == j)     {         return (req == (s[i] == 'T')) ? 1 : 0;     }      int ans = 0;     for (int k = i + 1; k < j; k += 1)     {          // Count Ways in which left substring         // evaluates to true and false.         int leftTrue = countRecur(i, k - 1, 1, s);         int leftFalse = countRecur(i, k - 1, 0, s);          // Count Ways in which right substring         // evaluates to true and false.         int rightTrue = countRecur(k + 1, j, 1, s);         int rightFalse = countRecur(k + 1, j, 0, s);          // Check if the combinations results         // to req.         if (evaluate(true, true, s[k]) == req)         {             ans += leftTrue * rightTrue;         }         if (evaluate(true, false, s[k]) == req)         {             ans += leftTrue * rightFalse;         }         if (evaluate(false, true, s[k]) == req)         {             ans += leftFalse * rightTrue;         }         if (evaluate(false, false, s[k]) == req)         {             ans += leftFalse * rightFalse;         }     }      return ans; } int countWays(string s) {     int n = s.length();     return countRecur(0, n - 1, 1, s); }  int main() {     string s = "T|T&F^T";     cout << countWays(s);     return 0; } 
Java
import java.util.*;  class GfG {      static boolean evaluate(boolean b1, boolean b2, char op)     {         if (op == '&') {             return b1 & b2;         }         else if (op == '|') {             return b1 | b2;         }         return b1 ^ b2;     }      // Function which returns the number of ways     // s[i:j] evaluates to req.     static int countRecur(int i, int j, boolean req,                           String s)     {          // Base case:         if (i == j) {             return (req == (s.charAt(i) == 'T')) ? 1 : 0;         }          int ans = 0;         for (int k = i + 1; k < j; k += 1) {              // Count Ways in which left substring             // evaluates to true and false.             int leftTrue = countRecur(i, k - 1, true, s);             int leftFalse = countRecur(i, k - 1, false, s);              // Count Ways in which right substring             // evaluates to true and false.             int rightTrue = countRecur(k + 1, j, true, s);             int rightFalse = countRecur(k + 1, j, false, s);              // Check if the combinations results             // to req.             if (evaluate(true, true, s.charAt(k)) == req) {                 ans += leftTrue * rightTrue;             }             if (evaluate(true, false, s.charAt(k)) == req) {                 ans += leftTrue * rightFalse;             }             if (evaluate(false, true, s.charAt(k)) == req) {                 ans += leftFalse * rightTrue;             }             if (evaluate(false, false, s.charAt(k))                 == req) {                 ans += leftFalse * rightFalse;             }         }          return ans;     }      static int countWays(String s)     {          int n = s.length();         return countRecur(0, n - 1, true, s);     }      public static void main(String[] args)     {         String s = "T|T&F^T";         System.out.println(countWays(s));     } } 
Python
# Python program to implement Boolean # Parenthesization Problem using recursion  # Function to evaluate a boolean condition  def evaluate(b1, b2, op):     if op == '&':         return b1 & b2     elif op == '|':         return b1 | b2     return b1 ^ b2  # Function which returns the number of ways # s[i:j] evaluates to req   def countRecur(i, j, req, s):      # Base case: When we have only one character     if i == j:         return 1 if req == (s[i] == 'T') else 0      ans = 0     # Loop through the operators (every other character is an operator)     for k in range(i + 1, j, 2):         # Count ways in which left and right substrings         # evaluate to True or False         leftTrue = countRecur(i, k - 1, True, s)         leftFalse = countRecur(i, k - 1, False, s)         rightTrue = countRecur(k + 1, j, True, s)         rightFalse = countRecur(k + 1, j, False, s)          # Check the result of applying the operator at position         # `k` to the subproblems         if evaluate(True, True, s[k]) == req:             ans += leftTrue * rightTrue         if evaluate(True, False, s[k]) == req:             ans += leftTrue * rightFalse         if evaluate(False, True, s[k]) == req:             ans += leftFalse * rightTrue         if evaluate(False, False, s[k]) == req:             ans += leftFalse * rightFalse      return ans  # Function to count the number of ways the expression # evaluates to True   def countWays(s):     n = len(s)     return countRecur(0, n - 1, True, s)   if __name__ == "__main__":     s = "T|T&F^T"     print(countWays(s)) 
C#
// C# program to implement Boolean // Parenthesization Problem using recursion using System;  class GfG {      static bool evaluate(bool b1, bool b2, char op)     {         if (op == '&') {             return b1 & b2;         }         else if (op == '|') {             return b1 | b2;         }         return b1 ^ b2;     }      // Function which returns the number of ways     // s[i:j] evaluates to req.     static int countRecur(int i, int j, bool req, string s)     {          // Base case:         if (i == j) {             return (req == (s[i] == 'T')) ? 1 : 0;         }          int ans = 0;         for (int k = i + 1; k < j; k += 1) {              // Count Ways in which left substring             // evaluates to true and false.             int leftTrue = countRecur(i, k - 1, true, s);             int leftFalse = countRecur(i, k - 1, false, s);              // Count Ways in which right substring             // evaluates to true and false.             int rightTrue = countRecur(k + 1, j, true, s);             int rightFalse = countRecur(k + 1, j, false, s);              // Check if the combinations results             // to req.             if (evaluate(true, true, s[k]) == req) {                 ans += leftTrue * rightTrue;             }             if (evaluate(true, false, s[k]) == req) {                 ans += leftTrue * rightFalse;             }             if (evaluate(false, true, s[k]) == req) {                 ans += leftFalse * rightTrue;             }             if (evaluate(false, false, s[k]) == req) {                 ans += leftFalse * rightFalse;             }         }          return ans;     }      static int countWays(string s)     {          int n = s.Length;         return countRecur(0, n - 1, true, s);     }      static void Main(string[] args)     {         string s = "T|T&F^T";         Console.WriteLine(countWays(s));     } } 
JavaScript
// JavaScript program to implement Boolean // Parenthesization Problem using recursion  // Function to evaluate a // boolean condition. function evaluate(b1, b2, op) {     if (op === "&") {         return b1 & b2;     }     else if (op === "|") {         return b1 | b2;     }     return b1 ^ b2; }  // Function which returns the number of ways // s[i:j] evaluates to req. function countRecur(i, j, req, s) {      // Base case:     if (i === j) {         return (req === 1) === (s[i] === "T") ? 1 : 0;     }      let ans = 0;     for (let k = i + 1; k < j; k += 1) {          // Count Ways in which left substring         // evaluates to true and false.         const leftTrue = countRecur(i, k - 1, 1, s);         const leftFalse = countRecur(i, k - 1, 0, s);          // Count Ways in which right substring         // evaluates to true and false.         const rightTrue = countRecur(k + 1, j, 1, s);         const rightFalse = countRecur(k + 1, j, 0, s);          // Check if the combinations results         // to req.         if (evaluate(1, 1, s[k]) === req) {             ans += leftTrue * rightTrue;         }         if (evaluate(1, 0, s[k]) === req) {             ans += leftTrue * rightFalse;         }         if (evaluate(0, 1, s[k]) === req) {             ans += leftFalse * rightTrue;         }         if (evaluate(0, 0, s[k]) === req) {             ans += leftFalse * rightFalse;         }     }      return ans; }  function countWays(s) {      let n = s.length;     return countRecur(0, n - 1, 1, s); }  // driver code const s = "T|T&F^T"; console.log(countWays(s)); 

Output
4

[Expected Approach 1]- Using Top-Down DP – O(n^3) Time and O(n^2) Space

If we notice carefully, we can observe that the above recursive solution holds the following two properties of Dynamic Programming:

1. Optimal Substructure: Number of ways to make expression s[i, j] evaluate to req depends on the optimal solutions of countWays(i, k-1, 0), countWays(i, k-1, 1), countWays(k+1, j, 0) and countWays(k+1, j, 1) where k lies between i and j.

2. Overlapping Subproblems: While applying a recursive approach in this problem, we notice that certain subproblems are computed multiple times. For example, countWays(0, 4, 1) and countWays(0, 7, 1) will call the same subproblem countWays(0, 2, 0) twice.

  • There are three parameters: i, j, req that changes in the recursive solution. So we create a 3D matrix of size n*n*2 for memoization.
  • We initialize this matrix as -1 to indicate nothing is computed initially.
  • Now we modify our recursive solution to first check if the value is -1, then only make recursive calls. This way, we avoid re-computations of the same subproblems.
Boolean-Parenthesization-Problem C++
#include <bits/stdc++.h> using namespace std;  // Function to evaluate a // boolean condition. bool evaluate(int b1, int b2, char op) {     if (op == '&')     {         return b1 & b2;     }     else if (op == '|')     {         return b1 | b2;     }     return b1 ^ b2; }  // Function which returns the number of ways // s[i:j] evaluates to req. int countRecur(int i, int j, int req, string &s, vector<vector<vector<int>>> &memo) {      // Base case:     if (i == j)     {         return (req == (s[i] == 'T')) ? 1 : 0;     }      // If value is memoized     if (memo[i][j][req] != -1)         return memo[i][j][req];      int ans = 0;     for (int k = i + 1; k < j; k += 1)     {          // Count Ways in which left substring         // evaluates to true and false.         int leftTrue = countRecur(i, k - 1, 1, s, memo);         int leftFalse = countRecur(i, k - 1, 0, s, memo);          // Count Ways in which right substring         // evaluates to true and false.         int rightTrue = countRecur(k + 1, j, 1, s, memo);         int rightFalse = countRecur(k + 1, j, 0, s, memo);          // Check if the combinations results         // to req.         if (evaluate(1, 1, s[k]) == req)         {             ans += leftTrue * rightTrue;         }         if (evaluate(1, 0, s[k]) == req)         {             ans += leftTrue * rightFalse;         }         if (evaluate(0, 1, s[k]) == req)         {             ans += leftFalse * rightTrue;         }         if (evaluate(0, 0, s[k]) == req)         {             ans += leftFalse * rightFalse;         }     }      return memo[i][j][req] = ans; } int countWays(string s) {     int n = s.length();     vector<vector<vector<int>>> memo(n, vector<vector<int>>(n, vector<int>(2, -1)));     return countRecur(0, n - 1, 1, s, memo); }  int main() {      string s = "T|T&F^T";     cout << countWays(s);     return 0; } 
Java
import java.util.Arrays;  class GfG {      // Function to evaluate a     // boolean condition.     static boolean evaluate(int b1, int b2, char op)     {         if (op == '&') {             return (b1 & b2) == 1;         }         else if (op == '|') {             return (b1 | b2) == 1;         }         return (b1 ^ b2) == 1;     }      // Function which returns the number of ways     // s[i:j] evaluates to req.     static int countRecur(int i, int j, int req, String s,                           int[][][] memo)     {          // Base case:         if (i == j) {             return (req == (s.charAt(i) == 'T' ? 1 : 0))                 ? 1                 : 0;         }          // If value is memoized         if (memo[i][j][req] != -1) {             return memo[i][j][req];         }          int ans = 0;         for (int k = i + 1; k < j; k += 1) {              // Count Ways in which left substring             // evaluates to true and false.             int leftTrue = countRecur(i, k - 1, 1, s, memo);             int leftFalse                 = countRecur(i, k - 1, 0, s, memo);              // Count Ways in which right substring             // evaluates to true and false.             int rightTrue                 = countRecur(k + 1, j, 1, s, memo);             int rightFalse                 = countRecur(k + 1, j, 0, s, memo);              // Check if the combinations result             // to req.             if (evaluate(1, 1, s.charAt(k)) == (req == 1)) {                 ans += leftTrue * rightTrue;             }             if (evaluate(1, 0, s.charAt(k)) == (req == 1)) {                 ans += leftTrue * rightFalse;             }             if (evaluate(0, 1, s.charAt(k)) == (req == 1)) {                 ans += leftFalse * rightTrue;             }             if (evaluate(0, 0, s.charAt(k)) == (req == 1)) {                 ans += leftFalse * rightFalse;             }         }          return memo[i][j][req] = ans;     }      static int countWays(String s)     {          int n = s.length();         int[][][] memo = new int[n][n][2];         for (int[][] mat : memo) {             for (int[] row : mat) {                 Arrays.fill(row, -1);             }         }         return countRecur(0, n - 1, 1, s, memo);     }      public static void main(String[] args)     {         String s = "T|T&F^T";         System.out.println(countWays(s));     } } 
Python
# Function to evaluate a # boolean condition. def evaluate(b1, b2, op):     if op == '&':         return b1 & b2     elif op == '|':         return b1 | b2     return b1 ^ b2  # Function which returns the number of ways # s[i:j] evaluates to req.   def countRecur(i, j, req, s, memo):      # Base case:     if i == j:         return 1 if req == (1 if s[i] == 'T' else 0) else 0      # If value is memoized     if memo[i][j][req] != -1:         return memo[i][j][req]      ans = 0     for k in range(i + 1, j, 2):          # Count Ways in which left substring         # evaluates to true and false.         left_true = countRecur(i, k - 1, 1, s, memo)         left_false = countRecur(i, k - 1, 0, s, memo)          # Count Ways in which right substring         # evaluates to true and false.         right_true = countRecur(k + 1, j, 1, s, memo)         right_false = countRecur(k + 1, j, 0, s, memo)          # Check if the combinations result         # to req.         if evaluate(1, 1, s[k]) == req:             ans += left_true * right_true         if evaluate(1, 0, s[k]) == req:             ans += left_true * right_false         if evaluate(0, 1, s[k]) == req:             ans += left_false * right_true         if evaluate(0, 0, s[k]) == req:             ans += left_false * right_false      memo[i][j][req] = ans     return ans   def countWays(s):      n = len(s)     memo = [[[-1 for _ in range(2)] for _ in range(n)] for _ in range(n)]     return countRecur(0, n - 1, 1, s, memo)   if __name__ == "__main__":     s = "T|T&F^T"     print(countWays(s)) 
C#
using System;  class GfG {      // Function to evaluate a     // boolean condition.     static bool evaluate(int b1, int b2, char op)     {         if (op == '&') {             return (b1 & b2) == 1;         }         else if (op == '|') {             return (b1 | b2) == 1;         }         return (b1 ^ b2) == 1;     }      // Function which returns the number of ways     // s[i:j] evaluates to req.     static int countRecur(int i, int j, int req, string s,                           int[, , ] memo)     {          // Base case:         if (i == j) {             return (req == (s[i] == 'T' ? 1 : 0)) ? 1 : 0;         }          // If value is memoized         if (memo[i, j, req] != -1) {             return memo[i, j, req];         }          int ans = 0;         for (int k = i + 1; k < j; k += 1) {              // Count Ways in which left substring             // evaluates to true and false.             int leftTrue = countRecur(i, k - 1, 1, s, memo);             int leftFalse                 = countRecur(i, k - 1, 0, s, memo);              // Count Ways in which right substring             // evaluates to true and false.             int rightTrue                 = countRecur(k + 1, j, 1, s, memo);             int rightFalse                 = countRecur(k + 1, j, 0, s, memo);              // Check if the combinations result             // to req.             if (evaluate(1, 1, s[k]) == (req == 1)) {                 ans += leftTrue * rightTrue;             }             if (evaluate(1, 0, s[k]) == (req == 1)) {                 ans += leftTrue * rightFalse;             }             if (evaluate(0, 1, s[k]) == (req == 1)) {                 ans += leftFalse * rightTrue;             }             if (evaluate(0, 0, s[k]) == (req == 1)) {                 ans += leftFalse * rightFalse;             }         }          return memo[i, j, req] = ans;     }      static int countWays(string s)     {          int n = s.Length;         int[, , ] memo = new int[n, n, 2];         for (int i = 0; i < n; i++) {             for (int j = 0; j < n; j++) {                 for (int k = 0; k < 2; k++) {                     memo[i, j, k] = -1;                 }             }         }         return countRecur(0, n - 1, 1, s, memo);     }      static void Main(string[] args)     {         string s = "T|T&F^T";         Console.WriteLine(countWays(s));     } } 
JavaScript
// Function to evaluate a // boolean condition. function evaluate(b1, b2, op) {     if (op === "&") {         return b1 & b2;     }     else if (op === "|") {         return b1 | b2;     }     return b1 ^ b2; }  // Function which returns the number of ways // s[i:j] evaluates to req. function countRecur(i, j, req, s, memo) {      // Base case:     if (i === j) {         return req === (s[i] === "T" ? 1 : 0) ? 1 : 0;     }      // If value is memoized     if (memo[i][j][req] !== -1) {         return memo[i][j][req];     }      let ans = 0;     for (let k = i + 1; k < j; k++) {          // Count Ways in which left substring         // evaluates to true and false.         let leftTrue = countRecur(i, k - 1, 1, s, memo);         let leftFalse = countRecur(i, k - 1, 0, s, memo);          // Count Ways in which right substring         // evaluates to true and false.         let rightTrue = countRecur(k + 1, j, 1, s, memo);         let rightFalse = countRecur(k + 1, j, 0, s, memo);          // Check if the combinations result         // to req.         if (evaluate(1, 1, s[k]) === req) {             ans += leftTrue * rightTrue;         }         if (evaluate(1, 0, s[k]) === req) {             ans += leftTrue * rightFalse;         }         if (evaluate(0, 1, s[k]) === req) {             ans += leftFalse * rightTrue;         }         if (evaluate(0, 0, s[k]) === req) {             ans += leftFalse * rightFalse;         }     }      return (memo[i][j][req] = ans); }  function countWays(s) {     let n = s.length;     let memo = Array.from(         {length : n},         () => Array.from({length : n},                          () => Array(2).fill(-1)));     return countRecur(0, n - 1, 1, s, memo); }  // driver code const s = "T|T&F^T"; console.log(countWays(s)); 

Output
4

[Expected Approach 2]- Using Bottom-Up DP – O(n^3) Time and O(n^2) Space

This problem is solved using tabulation (bottom-up DP). We define a 3D DP table where:

  • dp[i][j][1] stores the number of ways the subexpression s[i:j] evaluates to True.
  • dp[i][j][0] stores the number of ways the subexpression s[i:j] evaluates to False.

To fill the DP table, we iterate over all possible substrings s[i:j] and break them into two parts at every operator s[k]. The left part is s[i:k-1], and the right part is s[k+1:j]. Based on the operator (&, |, ^), we compute the number of ways to get True and False.

The final result is stored in dp[0][n-1][1], which gives the total ways to evaluate the full expression to True.

Illustration:


The iterative implementation is going to be tricky here we initially know diagonal values (which are 0), our result is going to be at the top right corner (or dp[0][n-1][1]) and we never access lower diagonal values. So we cannot fill the matrix with a normal traversal, we rather need to fill in diagonal manner. We fill the matrix using a variable len that stores differences between row and column indexes. We keep increasing len by 2 until it becomes n-1 (for the top right element)

C++
#include <bits/stdc++.h> using namespace std;  // Function to evaluate a boolean condition. bool evaluate(int b1, int b2, char op) {     if (op == '&')         return b1 & b2;     if (op == '|')         return b1 | b2;     return b1 ^ b2; }  // Function to count ways to parenthesize the expression to get 'True' int countWays(string s) {     int n = s.length();     vector<vector<vector<int>>> dp(n, vector<vector<int>>(n, vector<int>(2, 0)));      // Base case: Single operands (T or F)     for (int i = 0; i < n; i += 2)     {         dp[i][i][1] = (s[i] == 'T');         dp[i][i][0] = (s[i] == 'F');     }      // Iterate over different substring lengths     for (int len = 2; len < n; len += 2)     {             // len increases by 2 (odd indices are operators)         for (int i = 0; i < n - len; i += 2)         {             int j = i + len;                          // Reset values for the current subproblem             dp[i][j][0] = dp[i][j][1] = 0;               for (int k = i + 1; k < j; k += 2)             { // Iterate over operators                 char op = s[k];                 int leftTrue = dp[i][k - 1][1], leftFalse = dp[i][k - 1][0];                 int rightTrue = dp[k + 1][j][1], rightFalse = dp[k + 1][j][0];                  // Count ways to get True or False                 if (evaluate(1, 1, op))                     dp[i][j][1] += leftTrue * rightTrue;                 if (evaluate(1, 0, op))                     dp[i][j][1] += leftTrue * rightFalse;                 if (evaluate(0, 1, op))                     dp[i][j][1] += leftFalse * rightTrue;                 if (evaluate(0, 0, op))                     dp[i][j][1] += leftFalse * rightFalse;                  if (!evaluate(1, 1, op))                     dp[i][j][0] += leftTrue * rightTrue;                 if (!evaluate(1, 0, op))                     dp[i][j][0] += leftTrue * rightFalse;                 if (!evaluate(0, 1, op))                     dp[i][j][0] += leftFalse * rightTrue;                 if (!evaluate(0, 0, op))                     dp[i][j][0] += leftFalse * rightFalse;             }         }     }          // Return ways to make entire expression True     return dp[0][n - 1][1];  }  int main() {     string s = "T|T&F^T";     cout << countWays(s) << endl;     return 0; } 
Java
/*package whatever //do not write package name here */  import java.io.*;  class GfG {     static boolean evaluate(int b1, int b2, char op)     {         if (op == '&')             return (b1 & b2) == 1;         if (op == '|')             return (b1 | b2) == 1;         return (b1 ^ b2) == 1;     }      static int countWays(String s)     {         int n = s.length();         int[][][] dp = new int[n][n][2];          for (int i = 0; i < n; i += 2) {             dp[i][i][1] = (s.charAt(i) == 'T') ? 1 : 0;             dp[i][i][0] = (s.charAt(i) == 'F') ? 1 : 0;         }          for (int len = 2; len < n; len += 2) {             for (int i = 0; i < n - len; i += 2) {                 int j = i + len;                 dp[i][j][0] = dp[i][j][1] = 0;                  for (int k = i + 1; k < j; k += 2) {                     char op = s.charAt(k);                     int leftTrue = dp[i][k - 1][1],                         leftFalse = dp[i][k - 1][0];                     int rightTrue = dp[k + 1][j][1],                         rightFalse = dp[k + 1][j][0];                      if (evaluate(1, 1, op))                         dp[i][j][1] += leftTrue * rightTrue;                     if (evaluate(1, 0, op))                         dp[i][j][1]                             += leftTrue * rightFalse;                     if (evaluate(0, 1, op))                         dp[i][j][1]                             += leftFalse * rightTrue;                     if (evaluate(0, 0, op))                         dp[i][j][1]                             += leftFalse * rightFalse;                      if (!evaluate(1, 1, op))                         dp[i][j][0] += leftTrue * rightTrue;                     if (!evaluate(1, 0, op))                         dp[i][j][0]                             += leftTrue * rightFalse;                     if (!evaluate(0, 1, op))                         dp[i][j][0]                             += leftFalse * rightTrue;                     if (!evaluate(0, 0, op))                         dp[i][j][0]                             += leftFalse * rightFalse;                 }             }         }         return dp[0][n - 1][1];     }      public static void main(String[] args)     {         String s = "T|T&F^T";         System.out.println(countWays(s));     } } 
Python
def evaluate(b1, b2, op):     if op == '&':         return b1 & b2     if op == '|':         return b1 | b2     return b1 ^ b2   def countWays(s):     n = len(s)     dp = [[[0, 0] for _ in range(n)] for _ in range(n)]      # Base case: Single operands (T or F)     for i in range(0, n, 2):         dp[i][i][1] = 1 if s[i] == 'T' else 0         dp[i][i][0] = 1 if s[i] == 'F' else 0      # Iterate over different substring lengths     for length in range(2, n, 2):  # length increases by 2 (odd indices are operators)         for i in range(0, n - length, 2):             j = i + length             # Reset values for the current subproblem             dp[i][j][0] = dp[i][j][1] = 0              for k in range(i + 1, j, 2):  # Iterate over operators                 op = s[k]                 leftTrue, leftFalse = dp[i][k - 1][1], dp[i][k - 1][0]                 rightTrue, rightFalse = dp[k + 1][j][1], dp[k + 1][j][0]                  # Count ways to get True or False                 if evaluate(1, 1, op):                     dp[i][j][1] += leftTrue * rightTrue                 if evaluate(1, 0, op):                     dp[i][j][1] += leftTrue * rightFalse                 if evaluate(0, 1, op):                     dp[i][j][1] += leftFalse * rightTrue                 if evaluate(0, 0, op):                     dp[i][j][1] += leftFalse * rightFalse                  if not evaluate(1, 1, op):                     dp[i][j][0] += leftTrue * rightTrue                 if not evaluate(1, 0, op):                     dp[i][j][0] += leftTrue * rightFalse                 if not evaluate(0, 1, op):                     dp[i][j][0] += leftFalse * rightTrue                 if not evaluate(0, 0, op):                     dp[i][j][0] += leftFalse * rightFalse      return dp[0][n - 1][1]  # Return ways to make entire expression True   if __name__ == "__main__":     s = "T|T&F^T"     print(countWays(s)) 
C#
using System;  class GfG {     // Function to evaluate a boolean condition.     static bool Evaluate(int b1, int b2, char op)     {         if (op == '&')             return (b1 & b2) == 1;         if (op == '|')             return (b1 | b2) == 1;         return (b1 ^ b2) == 1;     }      // Function to count ways to parenthesize the expression     // to get 'True'     static int CountWays(string s)     {         int n = s.Length;         int[, , ] dp = new int[n, n, 2];          // Base case: Single operands (T or F)         for (int i = 0; i < n; i += 2) {             dp[i, i, 1] = (s[i] == 'T') ? 1 : 0;             dp[i, i, 0] = (s[i] == 'F') ? 1 : 0;         }          // Iterate over different substring lengths         for (int len = 2; len < n; len += 2) {             for (int i = 0; i < n - len; i += 2) {                 int j = i + len;                 dp[i, j, 0] = dp[i, j, 1] = 0;                  for (int k = i + 1; k < j; k += 2) {                     char op = s[k];                     int leftTrue = dp[i, k - 1, 1],                         leftFalse = dp[i, k - 1, 0];                     int rightTrue = dp[k + 1, j, 1],                         rightFalse = dp[k + 1, j, 0];                      if (Evaluate(1, 1, op))                         dp[i, j, 1] += leftTrue * rightTrue;                     if (Evaluate(1, 0, op))                         dp[i, j, 1]                             += leftTrue * rightFalse;                     if (Evaluate(0, 1, op))                         dp[i, j, 1]                             += leftFalse * rightTrue;                     if (Evaluate(0, 0, op))                         dp[i, j, 1]                             += leftFalse * rightFalse;                      if (!Evaluate(1, 1, op))                         dp[i, j, 0] += leftTrue * rightTrue;                     if (!Evaluate(1, 0, op))                         dp[i, j, 0]                             += leftTrue * rightFalse;                     if (!Evaluate(0, 1, op))                         dp[i, j, 0]                             += leftFalse * rightTrue;                     if (!Evaluate(0, 0, op))                         dp[i, j, 0]                             += leftFalse * rightFalse;                 }             }         }         return dp[0, n - 1, 1];     }      static void Main()     {         string s = "T|T&F^T";         Console.WriteLine(CountWays(s));     } } 
JavaScript
// Function to evaluate a boolean condition. function evaluate(b1, b2, op) {     if (op === "&")         return b1 & b2;     if (op === "|")         return b1 | b2;     return b1 ^ b2; }  // Function to count ways to parenthesize the expression to // get 'True' function countWays(s) {     let n = s.length;     let dp = Array.from(         {length : n},         () => Array.from({length : n}, () => [0, 0]));      // Base case: Single operands (T or F)     for (let i = 0; i < n; i += 2) {         dp[i][i][1] = s[i] === "T" ? 1 : 0;         dp[i][i][0] = s[i] === "F" ? 1 : 0;     }      // Iterate over different substring lengths     for (let len = 2; len < n; len += 2) {         for (let i = 0; i < n - len; i += 2) {             let j = i + len;             dp[i][j][0] = dp[i][j][1] = 0;              for (let k = i + 1; k < j; k += 2) {                 let op = s[k];                 let leftTrue = dp[i][k - 1][1],                     leftFalse = dp[i][k - 1][0];                 let rightTrue = dp[k + 1][j][1],                     rightFalse = dp[k + 1][j][0];                  if (evaluate(1, 1, op))                     dp[i][j][1] += leftTrue * rightTrue;                 if (evaluate(1, 0, op))                     dp[i][j][1] += leftTrue * rightFalse;                 if (evaluate(0, 1, op))                     dp[i][j][1] += leftFalse * rightTrue;                 if (evaluate(0, 0, op))                     dp[i][j][1] += leftFalse * rightFalse;                  if (!evaluate(1, 1, op))                     dp[i][j][0] += leftTrue * rightTrue;                 if (!evaluate(1, 0, op))                     dp[i][j][0] += leftTrue * rightFalse;                 if (!evaluate(0, 1, op))                     dp[i][j][0] += leftFalse * rightTrue;                 if (!evaluate(0, 0, op))                     dp[i][j][0] += leftFalse * rightFalse;             }         }     }     return dp[0][n - 1][1]; }  // Driver Code let s = "T|T&F^T"; console.log(countWays(s)); 

Output
4 





Next Article
Check for balanced parenthesis without using stack
author
kartik
Improve
Article Tags :
  • DSA
  • Dynamic Programming
  • Amazon
  • Linkedin
  • Microsoft
Practice Tags :
  • Amazon
  • Linkedin
  • Microsoft
  • Dynamic Programming

Similar Reads

  • What is Boolean Expression
    In this article, we will see what is Boolean Expression. Before starting with the topic directly lets us see what is a Boolean expression. It is an expression that always yields two values either true or false when evaluated. If the condition is true then it will return true or false and vice versa.
    4 min read
  • Remove Invalid Parentheses
    Given a string str consisting only of lowercase letters and the characters '(' and ')'. Your task is to delete minimum parentheses so that the resulting string is balanced, i.e., every opening parenthesis has a matching closing parenthesis in the correct order, and no extra closing parentheses appea
    15+ min read
  • Check for balanced parenthesis without using stack
    Given an expression string exp, write a program to examine whether the pairs and the orders of “{“, ”}”, ”(“, ”)”, ”[“, ”]” are correct in exp. Examples: Input : exp = “[()]{}{[()()]()}” Output : true Input : exp = “[(])” Output : falseRecommended: Please solve it on "PRACTICE" first, before moving
    9 min read
  • Evaluate a boolean expression represented as string
    Given a string consisting of only 0, 1, A, B, C where A = AND B = OR C = XOR Calculate the value of the string assuming no order of precedence and evaluation is done from left to right.Constraints – The length of string will be odd. It will always be a valid string. Example, 1AA0 will not be given a
    7 min read
  • Evaluation of Expression Tree
    Given a simple expression tree, consisting of basic binary operators i.e., + , - ,* and / and some integers, evaluate the expression tree. Examples: Input: Root node of the below tree Output:100 Input: Root node of the below tree Output: 110 Recommended PracticeExpression TreeTry It! Approach: The a
    9 min read
  • Problem solving on Boolean Model and Vector Space Model
    Boolean Model: It is a simple retrieval model based on set theory and boolean algebra. Queries are designed as boolean expressions which have precise semantics. Retrieval strategy is based on binary decision criterion. Boolean model considers that index terms are present or absent in a document. Pro
    4 min read
  • Mastering Bracket Problems for Competitive Programming
    Bracket problems in programming typically refer to problems that involve working with parentheses, and/or braces in expressions or sequences. It typically refers to problems related to the correct and balanced usage of parentheses, and braces in expressions or code. These problems often involve chec
    4 min read
  • Program to convert Infix notation to Expression Tree
    Given a string representing infix notation. The task is to convert it to an expression tree.Expression Tree is a binary tree where the operands are represented by leaf nodes and operators are represented by intermediate nodes. No node can have a single child. Construction of Expression tree The algo
    12 min read
  • Propositional Logic Notes for GATE Exam
    In the context of the GATE (Graduate Aptitude Test in Engineering) examination, Discrete Mathematics plays a crucial role) Topics in this domain include logic, set theory, combinatorics, graph theory, and relations. These Notes focus on the Propositional and first order logic of the discrete mathema
    9 min read
  • Relational Operators in C
    In C, relational operators are the symbols that are used for comparison between two values to understand the type of relationship a pair of numbers shares. The result that we get after the relational operation is a boolean value, that tells whether the comparison is true or false. Relational operato
    4 min read
geeksforgeeks-footer-logo
Corporate & Communications Address:
A-143, 7th Floor, Sovereign Corporate Tower, Sector- 136, Noida, Uttar Pradesh (201305)
Registered Address:
K 061, Tower K, Gulshan Vivante Apartment, Sector 137, Noida, Gautam Buddh Nagar, Uttar Pradesh, 201305
GFG App on Play Store GFG App on App Store
Advertise with us
  • Company
  • About Us
  • Legal
  • Privacy Policy
  • In Media
  • Contact Us
  • Advertise with us
  • GFG Corporate Solution
  • Placement Training Program
  • Languages
  • Python
  • Java
  • C++
  • PHP
  • GoLang
  • SQL
  • R Language
  • Android Tutorial
  • Tutorials Archive
  • DSA
  • Data Structures
  • Algorithms
  • DSA for Beginners
  • Basic DSA Problems
  • DSA Roadmap
  • Top 100 DSA Interview Problems
  • DSA Roadmap by Sandeep Jain
  • All Cheat Sheets
  • Data Science & ML
  • Data Science With Python
  • Data Science For Beginner
  • Machine Learning
  • ML Maths
  • Data Visualisation
  • Pandas
  • NumPy
  • NLP
  • Deep Learning
  • Web Technologies
  • HTML
  • CSS
  • JavaScript
  • TypeScript
  • ReactJS
  • NextJS
  • Bootstrap
  • Web Design
  • Python Tutorial
  • Python Programming Examples
  • Python Projects
  • Python Tkinter
  • Python Web Scraping
  • OpenCV Tutorial
  • Python Interview Question
  • Django
  • Computer Science
  • Operating Systems
  • Computer Network
  • Database Management System
  • Software Engineering
  • Digital Logic Design
  • Engineering Maths
  • Software Development
  • Software Testing
  • DevOps
  • Git
  • Linux
  • AWS
  • Docker
  • Kubernetes
  • Azure
  • GCP
  • DevOps Roadmap
  • System Design
  • High Level Design
  • Low Level Design
  • UML Diagrams
  • Interview Guide
  • Design Patterns
  • OOAD
  • System Design Bootcamp
  • Interview Questions
  • Inteview Preparation
  • Competitive Programming
  • Top DS or Algo for CP
  • Company-Wise Recruitment Process
  • Company-Wise Preparation
  • Aptitude Preparation
  • Puzzles
  • School Subjects
  • Mathematics
  • Physics
  • Chemistry
  • Biology
  • Social Science
  • English Grammar
  • Commerce
  • World GK
  • GeeksforGeeks Videos
  • DSA
  • Python
  • Java
  • C++
  • Web Development
  • Data Science
  • CS Subjects
@GeeksforGeeks, Sanchhaya Education Private Limited, All rights reserved
We use cookies to ensure you have the best browsing experience on our website. By using our site, you acknowledge that you have read and understood our Cookie Policy & Privacy Policy
Lightbox
Improvement
Suggest Changes
Help us improve. Share your suggestions to enhance the article. Contribute your expertise and make a difference in the GeeksforGeeks portal.
geeksforgeeks-suggest-icon
Create Improvement
Enhance the article with your expertise. Contribute to the GeeksforGeeks community and help create better learning resources for all.
geeksforgeeks-improvement-icon
Suggest Changes
min 4 words, max Words Limit:1000

Thank You!

Your suggestions are valuable to us.

What kind of Experience do you want to share?

Interview Experiences
Admission Experiences
Career Journeys
Work Experiences
Campus Experiences
Competitive Exam Experiences