[CF913E]Logical Expression
Logical Expression
题解
看到这题应该很容易想到暴力的,毕竟只有256种情况
但是,由于这是状压的题,必须用状压来做。否则T**M*E***又会***
定义为进行了i次操作,x,y,z的值的情况为j时的字典序最小表达式。
但我们很快就发现,因为有字典序的限制,并不是每一层都要加括号,非运算,或运算与与运算本身的优先级是不一样的。所以原本的dp法有问题。
重新定义,前两维含义与之前一样,k表示当前式子的优先级。
优先级0表示,存在一个或运算未在括号内进行,
优先级1表示,不存在或运算未在括号内进行,但存在一个与运算在括内进行,
优先级2表示,不存在或运算与与运算未在括号内进行。
至于非运算,直接加在式子外即可,毕竟它优先级最高。
初始状态也很好想,。
转移方法更好想,直接把符号加上即可。
源码
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int INF=0x7f7f7f7f;
const LL mo=1e9+7;
typedef pair<LL,LL> pii;
int n,a[10];
string dp[15][300][3];
void upd(string& trg,string org){
if(trg.empty())trg=org;
else if(org.size()<trg.size())trg=org;
else if(org<trg&&org.size()==trg.size())trg=org;
}
signed main(){
dp[0][0b00001111][2]='x';
dp[0][0b00110011][2]='y';
dp[0][0b01010101][2]='z';
for(int i=0;i<9;i++){
for(int j=0;j<(1<<8);j++){
if(!dp[i][j][0].empty())upd(dp[i+1][j][0],dp[i][j][0]);
if(!dp[i][j][1].empty())upd(dp[i+1][j][1],dp[i][j][1]);
if(!dp[i][j][2].empty())upd(dp[i+1][j][2],dp[i][j][2]);
if(!dp[i][j][0].empty())upd(dp[i+1][j][2],"("+dp[i][j][0]+")");
if(!dp[i][j][1].empty())upd(dp[i+1][j][2],"("+dp[i][j][1]+")");
if(!dp[i][j][2].empty())upd(dp[i+1][j][2],"("+dp[i][j][2]+")");
if(!dp[i][j][2].empty())upd(dp[i+1][(0b11111111)^j][2],"!"+dp[i][j][2]);
}
for(int j=0;j<(1<<8);j++)
for(int k=0;k<(1<<8);k++){
if(!dp[i][j][0].empty()&&!dp[i][k][1].empty())upd(dp[i+1][j|k][0],dp[i][j][0]+"|"+dp[i][k][1]);
if(!dp[i][j][0].empty()&&!dp[i][k][2].empty())upd(dp[i+1][j|k][0],dp[i][j][0]+"|"+dp[i][k][2]);
if(!dp[i][j][1].empty()&&!dp[i][k][1].empty())upd(dp[i+1][j|k][0],dp[i][j][1]+"|"+dp[i][k][1]);
if(!dp[i][j][1].empty()&&!dp[i][k][2].empty())upd(dp[i+1][j|k][0],dp[i][j][1]+"|"+dp[i][k][2]);
if(!dp[i][j][2].empty()&&!dp[i][k][1].empty())upd(dp[i+1][j|k][0],dp[i][j][2]+"|"+dp[i][k][1]);
if(!dp[i][j][2].empty()&&!dp[i][k][2].empty())upd(dp[i+1][j|k][0],dp[i][j][2]+"|"+dp[i][k][2]);
if(!dp[i][j][1].empty()&&!dp[i][k][2].empty())upd(dp[i+1][j&k][1],dp[i][j][1]+"&"+dp[i][k][2]);
if(!dp[i][j][2].empty()&&!dp[i][k][2].empty())upd(dp[i+1][j&k][1],dp[i][j][2]+"&"+dp[i][k][2]);
}
}
/*for(int i=0;i<(1<<8);i++){
string ans="";
upd(ans,dp[9][i][0]);
upd(ans,dp[9][i][1]);
upd(ans,dp[9][i][2]);
cout<<i<<":"<<ans<<endl;
}*/
scanf("%d",&n);
while(n--){
for(int i=0;i<8;i++)scanf("%1d",&a[i]);
int sum=0;for(int i=0;i<8;i++)sum<<=1,sum+=a[i];
string ans="";
upd(ans,dp[9][sum][0]);
upd(ans,dp[9][sum][1]);
upd(ans,dp[9][sum][2]);
cout<<ans<<endl;
}
return 0;
}

浙公网安备 33010602011771号