题目描述:给定一个布尔表达式以及一个布尔值,算出有多少种放括号的方法使得表达式的值为给定布尔值
思路:
(1)递归,从左到右对每个运算符求可能的情况,有很多重复子问题
(2)DP,dp[i][j][0]表示i到j之间的求值为0的方法数,dp[i][j][1]表示i到j之间求值为1的方法数
1 #include <iostream> 2 #include <queue> 3 #include <climits> 4 #include <algorithm> 5 #include <memory.h> 6 #include <stdio.h> 7 using namespace std; 8 9 int dp[100][100][2]; 10 int fun(int i,int j,bool flag,string s) 11 { 12 if(dp[i][j][(int)flag] != -1) 13 return dp[i][j][(int)flag]; 14 if(i > j) 15 return 0; 16 if(i == j) 17 { 18 int flagtmp = s[i]-'0'; 19 dp[i][j][flagtmp] = 1; 20 if(flagtmp) 21 dp[i][j][0] = 0; 22 else 23 dp[i][j][1] = 0; 24 return dp[i][j][(int)flag]; 25 } 26 int k; 27 dp[i][j][(int)flag] = 0; 28 if(flag) 29 { 30 for(k = i+1 ; k <= j;++k) 31 { 32 if(s[k] == '&') 33 { 34 if(dp[i][k-1][1] == -1) 35 { 36 dp[i][k-1][1] = fun(i,k-1,true,s); 37 } 38 if(dp[k+1][j][1] == -1) 39 { 40 dp[k+1][j][1] = fun(k+1,j,true,s); 41 } 42 dp[i][j][1] += dp[i][k-1][1]*dp[k+1][j][1]; 43 } 44 else if(s[k] == '|') 45 { 46 if(dp[i][k-1][1] == -1) 47 { 48 dp[i][k-1][1] = fun(i,k-1,true,s); 49 } 50 if(dp[k+1][j][1] == -1) 51 { 52 dp[k+1][j][1] = fun(k+1,j,true,s); 53 } 54 if(dp[i][k-1][0] == -1) 55 { 56 dp[i][k-1][0] = fun(i,k-1,false,s); 57 } 58 if(dp[k+1][j][0] == -1) 59 { 60 dp[k+1][j][0] = fun(k+1,j,false,s); 61 } 62 dp[i][j][1] += dp[i][k-1][1]*dp[k+1][j][1]; 63 dp[i][j][1] += dp[i][k-1][1]*dp[k+1][j][0]; 64 dp[i][j][1] += dp[k+1][j][1]*dp[i][k-1][0]; 65 } 66 else if(s[k] == '^') 67 { 68 if(dp[i][k-1][1] == -1) 69 { 70 dp[i][k-1][1] = fun(i,k-1,true,s); 71 } 72 if(dp[k+1][j][1] == -1) 73 { 74 dp[k+1][j][1] = fun(k+1,j,true,s); 75 } 76 if(dp[i][k-1][0] == -1) 77 { 78 dp[i][k-1][0] = fun(i,k-1,false,s); 79 } 80 if(dp[k+1][j][0] == -1) 81 { 82 dp[k+1][j][0] = fun(k+1,j,false,s); 83 } 84 dp[i][j][1] += (dp[i][k-1][1]*dp[k+1][j][0])+(dp[k+1][j][1]*dp[i][k-1][0]); 85 } 86 } 87 } 88 else 89 { 90 for(k = i+1 ; k <= j;++k) 91 { 92 if(s[k] == '&') 93 { 94 if(dp[i][k-1][1] == -1) 95 { 96 dp[i][k-1][1] = fun(i,k-1,true,s); 97 } 98 if(dp[k+1][j][1] == -1) 99 { 100 dp[k+1][j][1] = fun(k+1,j,true,s); 101 } 102 if(dp[i][k-1][0] == -1) 103 { 104 dp[i][k-1][0] = fun(i,k-1,false,s); 105 } 106 if(dp[k+1][j][0] == -1) 107 { 108 dp[k+1][j][0] = fun(k+1,j,false,s); 109 } 110 dp[i][j][0] += dp[i][k-1][0]*dp[k+1][j][1]; 111 dp[i][j][0] += dp[i][k-1][0]*dp[k+1][j][0]; 112 dp[i][j][0] += dp[i][k-1][1]*dp[k+1][j][0]; 113 } 114 else if(s[k] == '|') 115 { 116 if(dp[i][k-1][0] == -1) 117 { 118 dp[i][k-1][0] = fun(i,k-1,false,s); 119 } 120 if(dp[k+1][j][0] == -1) 121 { 122 dp[k+1][j][0] = fun(k+1,j,false,s); 123 } 124 dp[i][j][0] += dp[i][k-1][0]*dp[k+1][j][0]; 125 } 126 else if(s[k] == '^') 127 { 128 if(dp[i][k-1][1] == -1) 129 { 130 dp[i][k-1][1] = fun(i,k-1,true,s); 131 } 132 if(dp[k+1][j][1] == -1) 133 { 134 dp[k+1][j][1] = fun(k+1,j,true,s); 135 } 136 if(dp[i][k-1][0] == -1) 137 { 138 dp[i][k-1][0] = fun(i,k-1,false,s); 139 } 140 if(dp[k+1][j][0] == -1) 141 { 142 dp[k+1][j][0] = fun(k+1,j,false,s); 143 } 144 dp[i][j][0] += (dp[i][k-1][0]*dp[k+1][j][0])+(dp[k+1][j][1]*dp[i][k-1][1]); 145 } 146 } 147 } 148 return dp[i][j][(int)flag]; 149 } 150 151 int main() 152 { 153 memset(dp,-1,sizeof(dp)); 154 string s("1^0|0|1"); 155 cout<<fun(0,6,false,s)<<endl; 156 return 0; 157 }