資料結構 P1310 表示式的值

2022-06-20 00:51:12 字數 2674 閱讀 2189

【題目鏈結】

對於1 位二進位制變數定義兩種運算:

運算的優先順序是:

先計算括號內的,再計算括號外的。

「× 」運算優先於「⊕」運算,即計算表示式時,先計算× 運算,再計算⊕運算。例如:計算表示式a⊕b × c時,先計算 b × c,其結果再與 a 做⊕運算。

現給定乙個未完成的表示式,例如_+(_*_),請你在橫線處填入數字00或者11 ,請問有多少種填法可以使得表示式的值為00。

共 2 行。

第1 行為乙個整數 ll,表示給定的表示式中除去橫線外的運算子和括號的個數。

第2 行為乙個字串包含 ll 個字元,其中只包含』(』、』)』、』+』、』*』這44 種字元,其中』(』、』)』是左右括號,』+』、』*』分別表示前面定義的運算子「⊕」和「×」。這行字元按順序給出了給定表示式中除去變數外的運算子和括號。

共1 行。包含乙個整數,即所有的方案數。注意:這個數可能會很大,請輸出方案數對1000710007取模後的結果。

輸入 #1

4

+(*)

輸出 #1

【輸入輸出樣例說明】

給定的表示式包括橫線字元之後為:_+(_*_)

在橫線位置填入(0 、0 、0) 、(0 、1 、0) 、(0 、0 、1) 時,表示式的值均為0 ,所以共有3種填法。

【題解】

1、轉變為字尾表示式的形式,然後,如果是運算元要新增乙個數字,記住第乙個位置要多新增乙個『.』

2、然後進行推導,把四種情況的轉移狀態寫清楚。

字尾表示式是什麼呢?參見洛谷p1449

中綴表示式a + b*c + (d * e + f) * ga+b∗c+(d∗e+f)∗g,其轉換成字尾表示式則為a b c * + d e * f + g * +abc∗+de∗f+g∗+。

轉換過程需要用到棧,具體過程如下:

1)如果遇到運算元,我們就直接將其輸出。

2)如果遇到操作符,則我們將其放入到棧中,遇到左括號時我們也將其放入棧中。

3)如果遇到乙個右括號,則將棧元素彈出,將彈出的操作符輸出直到遇到左括號為止。注意,左括號只彈出並不輸出。

4)如果遇到任何其他的操作符,如(「+」, 「*」,「(」)等,從棧中彈出元素直到遇到發現更低優先順序的元素(或者棧為空)為止。彈出完這些元素後,才將遇到的操作符壓入到棧中。有一點需要注意,只有在遇到" ) "的情況下我們才彈出" ( ",其他情況我們都不會彈出" ( "。

5)如果我們讀到了輸入的末尾,則將棧中所有元素依次彈出。

備註:本題中我們用乙個"."來代表數字。掃瞄整個表示式(讀入的字串),如果當前位置不是括號(既不是左括號也不是右括號),就在字尾表示式裡填乙個"."表示這裡應有乙個數字。

狀態轉移方程很好想:

如果當前是"*":

f[0][now]=f[0][now]∗f[0][last]+f[0][now]∗f[1][last]+f[1][now]∗f[0][last]

f[1][now]=f[1][now]∗f[1][now]

(注意兩式順序不能顛倒,因為1式中需要用到f[1][now]f[1][now]的原始值)

如果當前是"+":

f[1][now]=f[1][now]∗f[1][last]+f[0][now]∗f[1][last]+f[1][now]∗f[0][last]

f[0][now]=f[0][now]∗f[1][last]

(兩式的順序同樣不能顛倒)

其中,f[i][j]表示j號數字是i的情況有多少種,初始化為1

【**】

1 #include2

using

namespace

std;

3const

int mod = 10007;4

const

int n = 1e5+10;5

6int f[2

][n] ;78

int priority( char

s )15}16

17void tosuffixstring( string &s )else

*/27

if( s[i] == '

(' || s[i] == '*'

)else

if( s[i] == ')'

)34//出來的時候,棧頂為(.

35op.pop();

36 }else

41//

出來的時候,棧裡面的運算子優先順序低於當前位置.

42op.push( s[i] ) ;43}

44if( !(s[i] == '

(' || s[i] == ')'

) )47}48

while( !op.empty() )

52//

cout << res << endl ;

53 s =res ;54}

5556

void calc( string

s )else

if( s[i] == '*'

)else

if( s[i] == '+'

)80}81 cout << f[0][1] <

8384

intmain()

view code

P1310 表示式的值

原題鏈結 water lift 一波講解,然後我們就會了這個題,然後我們就要寫部落格啦qwq 這是個布林表示式基計數問題。這個其實 就是 或運算,就是 與運算。我們將這個式子通俗得看成 x y 和 x y 我們設x0是使x為0的方案數,x1是使x為1的方案數 y0是使y為0的方案數,y1是使y為1的...

洛谷 P1310 表示式的值(棧 DP)

首先因為有優先順序和括號,可以先把表示式化成字尾表示式的形式,其中用 表示這乙個點是數字。用u記錄得到0的方案數,v記錄得到1的方案數。設兩個步驟的運算結果經過每個符號到乙個結果時,第乙個運算結果算出0的方案數為t1,1的方案數為t2。第二個算出0的方案數為t3,算出1的方案數為t4。則有 當符號是...

洛谷 P1310 表示式的值 解題報告

對於1 位二進位制變數定義兩種運算 運算的優先順序是 先計算括號內的,再計算括號外的。運算優先於 運算,即計算表示式時,先計算 運算,再計算 運算。例如 計算表示式a b c時,先計算 b c,其結果再與 a 做 運算。現給定乙個未完成的表示式,例如 請你在橫線處填入數 0或者1 請問有多少種填法可...