对于一个只由0(假)、1(真)、&(逻辑与)、|(逻辑或)和^(异或)五种字符组成的逻辑表达式,再给定一个结果值。现在可以对这个没有括号的表达式任意加合法的括号,返回得到能有多少种加括号的方式,可以达到这个结果。
给定一个字符串表达式exp及它的长度len,同时给定结果值ret,请返回方案数。保证表达式长度小于等于300。为了防止溢出,请返回答案Mod 10007的值。
测试样例:
"1^0|0|1",7,0
返回:2
对于一个只由0(假)、1(真)、&(逻辑与)、|(逻辑或)和^(异或)五种字符组成的逻辑表达式,再给定一个结果值。现在可以对这个没有括号的表达式任意加合法的括号,返回得到能有多少种加括号的方式,可以达到这个结果。
给定一个字符串表达式exp及它的长度len,同时给定结果值ret,请返回方案数。保证表达式长度小于等于300。为了防止溢出,请返回答案Mod 10007的值。
"1^0|0|1",7,0
返回:2
public static int countWays(String exp, int len, int ret) { int n=len/2+1; int[][][] dp=new int[n][n][2];//dp[l][r][p],从l到r范围,可以得到p结果的个数 char[] op=new char[n-1]; int[] num=new int[n]; for(int i=0;i<len-1;i+=2){ num[i/2]=exp.charAt(i)-'0'; op[i/2]=exp.charAt(i+1); } num[n-1]=exp.charAt(len-1)-'0'; for(int l=0;l<n;l++){ for(int i=0;i+l<n;i++){ if(l==0){ dp[i][i][num[i]]=1; dp[i][i][num[i]^1]=0; } else{ int n0=0,n1=0; for(int j=i;j<i+l;j++){ int p00,p01,p11; p00=(dp[i][j][0]%10007)*(dp[j+1][i+l][0]%10007)%10007; p01=(dp[i][j][0]%10007)*(dp[j+1][i+l][1]%10007)%10007+(dp[i][j][1]%10007)*(dp[j+1][i+l][0]%10007)%10007; p11=(dp[i][j][1]%10007)*(dp[j+1][i+l][1]%10007)%10007; switch(op[j]){ case '|': n0+=p00; n1+=p01+p11; break; case '&': n0+=p00+p01; n1+=p11; break; case '^': n0+=p00+p11; n1+=p01; break; } } n0%=10007; n1%=10007; dp[i][i+l][0]=n0; dp[i][i+l][1]=n1; } } } return dp[0][n-1][ret]; }
import java.util.*; public class Expression { public int cal(int d1, int d2, char op) { if (op == '&') { return d1 & d2; } else if (op == '|') { return d1 | d2; } else { return d1 ^ d2; } } public int count(int[] digits, char[] ops, int des) { int n = digits.length; int[][][] dp = new int[n][n][2]; for (int i = 0; i < n; ++i) { if (digits[i] == 1) { ++dp[i][i][1]; } else { ++dp[i][i][0]; } } for (int x = 1; x < digits.length; ++x) { for (int i = 0; i < digits.length - x; ++i) { int j = i + 1 + x - 1; for (int k = i; k < j; ++k) { if (dp[i][k][0] != 0 && dp[k + 1][j][0] != 0) { int num = cal(0, 0, ops[k]); dp[i][j][num] = (dp[i][j][num] + dp[i][k][0] * dp[k + 1][j][0]) % 10007; } if (dp[i][k][0] != 0 && dp[k + 1][j][1] != 0) { int num = cal(0, 1, ops[k]); dp[i][j][num] = (dp[i][j][num] + dp[i][k][0] * dp[k + 1][j][1]) % 10007; } if (dp[i][k][1] != 0 && dp[k + 1][j][0] != 0) { int num = cal(1, 0, ops[k]); dp[i][j][num] = (dp[i][j][num] + dp[i][k][1] * dp[k + 1][j][0]) % 10007; } if (dp[i][k][1] != 0 && dp[k + 1][j][1] != 0) { int num = cal(1, 1, ops[k]); dp[i][j][num] = (dp[i][j][num] + dp[i][k][1] * dp[k + 1][j][1]) % 10007; } } } } return dp[0][n - 1][des]; } public int countWays(String exp, int len, int ret) { // write code here char[] exps = exp.toCharArray(); int[] digits = new int[(exps.length + 1) / 2]; char[] ops = new char[(exps.length - 1) / 2]; for (int i = 0; i < exps.length; ++i) { if (i % 2 == 0) { digits[i / 2] = Integer.valueOf(exps[i] - '0'); } else { ops[i / 2] = exps[i]; } } return count(digits, ops, ret) % 10007; } }