原題鏈結
water_lift 一波講解,然後我們就會了這個題,然後我們就要寫部落格啦qwq~
這是個布林表示式基計數問題。
這個其實⊕就是「|」或運算,×就是「&」與運算。
我們將這個式子通俗得看成:x&y 和 x|y
我們設x0是使x為0的方案數,x1是使x為1的方案數;y0是使y為0的方案數,y1是使y為1的方案數;使x&
y'>x&y
為1的方案數?為0的方案數?使x|
y'>x|y
為1的方案數?為0的方案數?
不難發現:
使x&y
'>x&y
為1,那麼x
'>x
和y'>
y都要為1,所以方案數為x1∗
y1'>x1∗y1
。使x&y
'>
x&y為0,那麼x
'>x
和y'>y不
都為1,所以方案數為x1∗
y0+x
0∗y1
+x0∗
y0'>x1∗y0+x0∗y1+x0∗y0
。使x|y
'>
x|y為1的方案數為x1∗
y1+x
0∗y1
+x1∗
y0'>x1∗y1+x0∗y1+x1∗y0
,為0的方案數為x0∗
y0'>x0∗y0
。x|y'>x1∗
y1+x
0∗y1
+x1∗
y0'>x0∗
y0'>然後我們發現給出的式子乙個特別煩的東東就是: 有括號x|
y'>x1∗
y1+x
0∗y1
+x1∗
y0'>x0∗
y0'>為了去掉括號,我們可以考慮將題目輸入的中綴表示式給它換成字尾表示式(字尾表示式的好處就是式子中沒有括號!)x|
y'>x1∗
y1+x
0∗y1
+x1∗
y0'>x0∗
y0'>腫麼換呢?這確實是乙個難題,還好我們找到了這樣乙個方法(由於太蒟還不會證正確性):
遍歷中綴表示式:
遇到數字,直接放入答案序列
遇到左括號,入棧
遇到右括號,把棧頂到上乙個左括號的元素依次出棧並放入答案序列
遇到乘號,入棧
遇到加號,從棧頂開始彈出這段連續的乘號,並放入答案序列,最後加號入棧
最後把棧裡剩下的元素依次放入答案序列
為什麼是正確的呢?貼一下water_lift的模擬過程(想要更豐富的展現?請看water_lift的部落格):
那麼有了字尾表示式,這麼求值?
遇到數字入棧,遇到運算符號就取出棧頂的兩個元素,將它們進行該運算子的運算後再入棧。
the last question:
題目要求的是使得表示式為0的方案數,那麼在哪填數字?
看一下樣例:
很顯然就是在這幾個標紅的位置填數字啦:
_+(_*_)
so,我們可以總結一下在**填數字: 式子最前面一定要填個數字(你見哪個式子是符號打頭?),然後「+」和「×」後面要填乙個數字!
到這裡咱們就可以食用**啦:
#include usingnamespace
std;
stack
fh; //
中綴表示式轉字尾表示式的時候所要用到的存符號的棧
stack zero; //
乙個存使表示式為0的方案數的棧
stack one; //
乙個存使表示式為1的方案數的棧
string houxu; //
轉化後的字尾表示式
char ch[100001]; //
存輸入的字串
intn,l0,l1,r0,r1;
//這裡l0就是上文的x0,l1是x1,r0是y0,r1是y1
const
int mod=10007
;int
main()
if(ch[i]=='
+') //
如果是'+',要把符號棧棧頂的'*' 都放入字尾表示式的後面
fh.push(ch[i]);
}if(ch[i]=='
)') //
如果是')',則要把'('和')'之間的符號放入字尾表示式的後面
fh.pop();
//彈出左括號
}
if(ch[i]!='
('&&ch[i]!='
)') houxu.push_back('
n'); //
如果不是括號,也就是說如果是'+'或'*',那麼就要在後面填乙個數字
}
while(!fh.empty()) //
將符號棧中剩餘的符號全部放入字尾表示式
for(int i=0;i//
可以看成是字尾表示式求值
else
//如果是符號
else
//|運算 }}
printf("%d
",zero.top()%mod); //
最後剩下的就是使整個表示式為0的方案數
return0;
}
資料結構 P1310 表示式的值
題目鏈結 對於1 位二進位制變數定義兩種運算 運算的優先順序是 先計算括號內的,再計算括號外的。運算優先於 運算,即計算表示式時,先計算 運算,再計算 運算。例如 計算表示式a b c時,先計算 b c,其結果再與 a 做 運算。現給定乙個未完成的表示式,例如 請你在橫線處填入數字00或者11 請問...
洛谷 P1310 表示式的值(棧 DP)
首先因為有優先順序和括號,可以先把表示式化成字尾表示式的形式,其中用 表示這乙個點是數字。用u記錄得到0的方案數,v記錄得到1的方案數。設兩個步驟的運算結果經過每個符號到乙個結果時,第乙個運算結果算出0的方案數為t1,1的方案數為t2。第二個算出0的方案數為t3,算出1的方案數為t4。則有 當符號是...
洛谷 P1310 表示式的值 解題報告
對於1 位二進位制變數定義兩種運算 運算的優先順序是 先計算括號內的,再計算括號外的。運算優先於 運算,即計算表示式時,先計算 運算,再計算 運算。例如 計算表示式a b c時,先計算 b c,其結果再與 a 做 運算。現給定乙個未完成的表示式,例如 請你在橫線處填入數 0或者1 請問有多少種填法可...