Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.io.File;
- import java.io.IOException;
- import java.io.PrintWriter;
- import java.util.ArrayList;
- import java.util.Scanner;
- public class Main {
- static class Task {
- public final static String INPUT_FILE = "in";
- public final static String OUTPUT_FILE = "out";
- private final static int MOD = 1000000007;
- int n;
- char[] v;
- private void readInput() {
- try {
- Scanner sc = new Scanner(new File(INPUT_FILE));
- n = sc.nextInt();
- String s = sc.next().trim();
- s = " " + s;
- v = s.toCharArray();
- sc.close();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
- private void writeOutput(int result) {
- try {
- PrintWriter pw = new PrintWriter(new File(OUTPUT_FILE));
- pw.printf("%d\n", result);
- pw.close();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
- private Boolean OperandValue(char x) {
- if (x == 'T') {
- return true;
- }
- return false;
- }
- private Boolean isOperator(char x) {
- if (x == '&' || x == '|' || x == '^')
- return true;
- return false;
- }
- private int getResult() {
- // TODO: Calculati numarul de moduri in care se pot aseza
- // parantezele astfel incat rezultatul expresiei sa fie TRUE.
- // Numarul de moduri se va calcula modulo MOD (1000000007).
- int nrOperands = n / 2 + 1;
- int[][] dpTrue = new int[nrOperands + 1][nrOperands + 1];
- int[][] dpFalse = new int[nrOperands + 1][nrOperands + 1];
- for (int i = 1, op = 1; i <= nrOperands; i++, op += 2) {
- if (OperandValue(v[op])) {
- dpTrue[i][i] = 1;
- dpFalse[i][i] = 0;
- } else {
- dpTrue[i][i] = 0;
- dpFalse[i][i] = 1;
- }
- }
- // Creez lista de operatori
- ArrayList<Character> operators = new ArrayList<Character>();
- for (int i = 0; i < v.length; i++) {
- if (isOperator(v[i])) {
- operators.add(v[i]);
- }
- }
- for (int len = 2; len <= nrOperands; len++) {
- for (int i = 1; i + len - 1 <= nrOperands; i++) {
- int j = i + len - 1;
- for (int k = i; k < j; k++) {
- int tot1 = (dpTrue[i][k] % MOD + dpFalse[i][k] % MOD) % MOD;
- int tot2 = (dpTrue[k + 1][j] % MOD + dpFalse[k + 1][j] % MOD) % MOD;
- if (operators.get(k - 1) == '&') {
- dpTrue[i][j] = (int) ((dpTrue[i][j] + 1L*dpTrue[i][k] % MOD * dpTrue[k + 1][j] % MOD) % MOD);
- dpFalse[i][j] = (int) ((dpFalse[i][j] + (1L*tot1 * tot2) % MOD - (1L*dpTrue[i][k] * dpTrue[k + 1][j]) % MOD + MOD)
- % MOD);
- }
- if (operators.get(k - 1) == '|') {
- dpTrue[i][j] = (int) ((dpTrue[i][j] + (1L*tot1 * tot2) % MOD - (1L*dpFalse[i][k] * dpFalse[k + 1][j]) % MOD + MOD)
- % MOD);
- dpFalse[i][j] = (int) ((dpFalse[i][j] + 1L*dpFalse[i][k] % MOD * dpFalse[k + 1][j] % MOD) % MOD);
- }
- if (operators.get(k - 1) == '^') {
- dpTrue[i][j] = (int) ((dpTrue[i][j] + (1L*dpTrue[i][k] * dpFalse[k + 1][j]) % MOD
- + (1L*dpFalse[i][k] * dpTrue[k + 1][j]) % MOD) % MOD);
- dpFalse[i][j] = (int) ((dpFalse[i][j] + (1L*dpTrue[i][k] * dpTrue[k + 1][j]) % MOD
- + (1L*dpFalse[i][k] * dpFalse[k + 1][j]) % MOD) % MOD);
- }
- }
- }
- }
- return dpTrue[1][nrOperands];
- }
- public void solve() {
- readInput();
- writeOutput(getResult());
- }
- }
- public static void main(String[] args) {
- new Task().solve();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement