每日一題 5月7日題目精講 火 皇家烈焰

2021-10-05 21:39:14 字數 2990 閱讀 1709

「火」皇家烈焰

時間限制:c/c++

1秒,其他語言2秒

空間限制:c/c++

262144k,其他語言524288k

64bit io format:

%lld

帕秋莉掌握了一種火屬性魔法

由於鍾愛掃雷遊戲,帕秋莉把自己圖書館前的走廊看作乙個一維的掃雷地圖,她製造了很多烈焰,排在這條走廊內

現在帕秋莉告訴你一部分烈焰的分布情況,請你告訴她可能的情況有多少種

對於乙個格仔,裡面會有以下幾種字元:

0:這個格仔沒有烈焰,且其左右兩個格仔均沒有烈焰

1:這個格仔沒有烈焰,且其左右兩個格仔中只有乙個烈焰

2:這個格仔沒有烈焰,且其左右兩個格仔中均有烈焰

*:這個格仔有烈焰

?:未告訴你本格情況

輸入描述:

乙個字串

輸出描述:

輸出一行,乙個整數表示答案,對1e9+7取模

示例1

輸入

?

1?

輸出

2
說明

已知第二個格仔左右有乙個烈焰

因此可能的情況有10和01,顯然其他情況都無法滿足已知條件的要求

備註:字串的長度為n

對於30%的資料,n≤20

對於60%的的資料,n≤1,000

對於100%的資料,n≤1,000,000

乍一看以為是掃雷。仔細一看為什麼又是dp(每日一題好愛出dp,而我dp又是渣渣)

在其他大佬那吸取知識之後,寫出自己的理解:

我們仔細看題可以看出,每個點什麼情況其實都與兩側的點息息相關,我可以通過乙個點算出兩側點的狀態,也可以根據兩側狀態來反推中間的點。

但是我們狀態轉移的順序是從左到右,我們在轉移過程中,考慮第i點時,i-1之前的點狀態都是固定的,所以我們只需要考慮當前點i與之後乙個點i+1的狀態。

在第i點時,i+1可能也有了要求,所以不滿足情況的就不用轉移狀態。

dp[i][0/1/2/3]:

0表示i與i+1都不是火

1表示i是火,i+1不是火

2表示i不是火,i+1是

3表示i和i+1都是火

對照題目給出的狀態,

0:這個格仔沒有烈焰,且其左右兩個格仔均沒有烈焰

1:這個格仔沒有烈焰,且其左右兩個格仔中只有乙個烈焰

2:這個格仔沒有烈焰,且其左右兩個格仔中均有烈焰

*:這個格仔有烈焰

?:未告訴你本格情況

具體情況如下:

if(i = = 0)

說明i-1,i,i+1都沒有火,i 的狀態就是等同於i-1的狀態都是0(即本身與右邊都不是火)

轉移方程:f [i ] [ 0 ] = f [ i - 1 ] [ 0 ]

if(i = = 1)

i不是火,但是i的周圍有乙個火

如果左邊是火,那麼右邊就不是火,那i就滿足狀態0,i-1就滿足狀態1:f[i][0]=f[i-1][1]

如果右邊是火,左邊就不是火,那麼i就滿足狀態2,i-1就滿足狀態0:f [ i ][ 2 ] = f [ i - 1 ] [ 0]

if(i = = 2)

左右均為火,那麼i-1是火,i不是火,i+1是火,i就滿足狀態2: f [ i ] [ 2 ] =f [ i-1 ] [ 1 ]

if(i = = *)

當前i為火,i+1有兩種情況,

乙個是i+1位火:

f [ i ] [ 3 ]= f [ i - 1 ] [ 2 ] + f [ i - 1 ] [ 3 ]

i+1不是火:

f [ i ] [ 1 ] = f [ i - 1 ] [ 2 ] + f [ i - 1 ] [ 3 ]

if(i = = ?)

當前點未知,我們就要考慮所有情況

i為火,i不為火,i+1為火,i+1不為火

四種情況:

i與i+1都不是火:

f [ i ] [0 ] = f[ i - 1 ][ 0 ] + f [i - 1 ] [ 1 ]

i不是,i+1是火

f [ i ] [ 2 ] = f [ i - 1 ] [ 0 ] + f [ i - 1 ] [ 1 ]

i是火,i+1不是

f [ i ] [ 1 ] = f [ i - 1 ] [ 2 ] + f [i - 1 ] [ 3 ]

i和i+1都是火

f [ i ] [ 3 ] = f [ i - 1 ] [ 2 ] + f [ i - 1 ][ 3 ]

到最後乙個點i,i後面沒有點了,相當於i+1不是火

答案就是

i是火與不是火了兩種情況加一起

f [ i ] [ 0 ] + f [ i ] [ 1 ]

此時i=地圖長度

對了前往不要忘了取模mod

結合我講的,在**裡面一條一條對應

#include

using

namespace std;

const

int maxn=

1e6+

1,mod=

1e9+7;

int f[maxn][7

];char s[maxn]

;int

main()

else

if(s[i-1]

=='1'

)else

if(s[i-1]

=='2'

)else

if(s[i-1]

=='*'

)else

if(s[i-1]

=='?')}

cout<<

(f[len][0

]+f[len][1

])%mod;

return0;

}

每日一題 4月7日題目精講 樹

樹 時間限制 c c 1秒,其他語言2秒 空間限制 c c 131072k 其他語言262144k 64bit io format lld 題目描述 shy有一顆樹,樹有n個結點。有k種不同顏色的染料給樹染色。乙個染色方案是合法的,當且僅當對於所有相同顏色的點對 x,y x到y的路徑上的所有點的顏色...

每日一題 7月1日題目精講 借教室

時間限制 c c 1秒,其他語言2秒 空間限制 c c 131072k,其他語言262144k 64bit io format lld 在大學期間,經常需要租借教室。大到院系舉辦活動,小到學習小組自習討論,都需要向學校申請借教室。教室的大小功能不同,借教室人的身份不同,借教室的手續也不一樣。面對海量...

每日一題 8月7日題目精講 雙棧排序

時間限制 c c 1秒,其他語言2秒 空間限制 c c 131072k,其他語言262144k 64bit io format lld tom最近在研究乙個有趣的排序問題。如圖所示,通過2個棧s1和s2,tom希望借助以下4種操作實現將輸入序列公升序排序。操作a 如果輸入序列不為空,將第乙個元素壓入...