Evaluate Expression To True

Given an expression, A, with operands and operators (OR , AND , XOR), in how many ways can you evaluate the expression to true, by grouping in different ways?

Operands are only true and false.

Return the number of ways to evaluate the expression modulo 103 + 3.


Input Format:

The first and the only argument of input will contain a string, A.

The string A, may contain these characters:
    '|' will represent or operator 
    '&' will represent and operator
    '^' will represent xor operator
    'T' will represent true operand
    'F' will false

Output:

Return an integer, representing the number of ways to evaluate the string.

Constraints:

1 <= length(A) <= 150

Example:

Input 1:
    A = "T|F"

Output 1:
    1

Explanation 1:
    The only way to evaluate the expression is:
        => (T|F) = T 

Input 2:
    A = "T^T^F"
    
Output 2:
    0
    
Explanation 2:
    There is no way to evaluate A to a true statement.
Solution:

Time: O(n^3)
Space: O(n^2)

public class Solution {
    public int cnttrue(String A) {
        // t[i][j] = number of ways to evalute A to true from ith to jth element
        // f[i][j] = number of ways to evalute A to false from ith to jth element
        // t[i][j] += dp[i][k] * dp[k + 2][j] for k < j, k += 2
        // t[1][n]
        int MOD = 1003;
        int n = A.length();
        int[][] t = new int[n + 1][n + 1];
        int[][] f = new int[n + 1][n + 1];
        for (int len = 0; len < n; len += 2) {
            for (int i = 1; i <= n; i += 2) {
                int j = i + len;
                if (i == j) {
                    boolean c = A.charAt(i - 1) == 'T';
                    t[i][j] = c ? 1 : 0;
                    f[i][j] = 1 - t[i][j];
                } else if (j <= n && j - i == 2) {
                    char operator = A.charAt(i);
                    boolean left = A.charAt(i - 1) == 'T';
                    boolean right = A.charAt(j - 1) == 'T';
                    if (operator == '|') {
                        t[i][j] = left || right ? 1 : 0;
                    } else if (operator == '&') {
                        t[i][j] = left && right ? 1 : 0;
                    } else if (operator == '^') {
                        t[i][j] = left ^ right ? 1 : 0;
                    }
                    f[i][j] = 1 - t[i][j];
                } else if (j <= n) {
                    // i   j
                    // 1234567
                    // T^F|F&T
                    for (int k = i; k < j; k += 2) {
                        char operator = A.charAt(k);
                        if (operator == '|') {
                            t[i][j] += (t[i][k] * t[k + 2][j]) % MOD;
                            t[i][j] += (t[i][k] * f[k + 2][j]) % MOD;
                            t[i][j] += (f[i][k] * t[k + 2][j]) % MOD;
                            f[i][j] += (f[i][k] * f[k + 2][j]) % MOD;
                        } else if (operator == '&') {
                            t[i][j] += (t[i][k] * t[k + 2][j]) % MOD;
                            f[i][j] += (t[i][k] * f[k + 2][j]) % MOD;
                            f[i][j] += (f[i][k] * t[k + 2][j]) % MOD;
                            f[i][j] += (f[i][k] * f[k + 2][j]) % MOD;
                        } else if (operator == '^') {
                            f[i][j] += (t[i][k] * t[k + 2][j]) % MOD;
                            t[i][j] += (t[i][k] * f[k + 2][j]) % MOD;
                            t[i][j] += (f[i][k] * t[k + 2][j]) % MOD;
                            f[i][j] += (f[i][k] * f[k + 2][j]) % MOD;
                        }
                    }
                }
            }
        }
        // for (int[] a : t) {
        //     System.out.println(Arrays.toString(a));
        // }
        // System.out.println("~~~~~~~~~~~~");
        // for (int[] a : f) {
        //     System.out.println(Arrays.toString(a));
        // }
        return t[1][n] % MOD;
    }
}