POJ 1187 隕石的秘密 (線性DP)

2022-06-28 05:00:09 字數 2124 閱讀 9945

題意:

公元12023年,一顆巨大的隕石墜落在南極。於是,災難降臨了,地球上出現了一系列反常的現象。當人們焦急萬分的時候,一支中國科學家組成的南極考察隊趕到了出事地點。經過一番偵察,科學家們發現隕石上刻有若干行密文,每一行都包含5個整數: 

1 1 1 1 6 

0 0 6 3 57 

8 0 11 3 2845 

著名的科學家ss發現,這些密文實際上是一種複雜運算的結果。為了便於大家理解這種運算,他定義了一種ss表示式: 

1. ss表示式是僅由'','[',']','(',')'組成的字串。 

2. 乙個空串是ss表示式。 

3. 如果a是ss表示式,且a中不含字元'','[',']',則(a)是ss表示式。 

4. 如果a是ss表示式,且a中不含字元'',則[a]是ss表示式。 

5. 如果a是ss表示式,則是ss表示式。 

6. 如果a和b都是ss表示式,則ab也是ss表示式。 

例如 ()(())  } 

都是ss表示式。 

而 ()()() 

[() 

不是ss表示式。 

乙個ss表示式e的深度d(e)定義如下: 

例如()的深度為2。 

密文中的複雜運算是這樣進行的: 

設密文中每行前4個數依次為l1,l2,l3,d,求出所有深度為d,含有l1對{},l2對,l3對()的ss串的個數,並用這個數對當前的年份11380求餘數,這個餘數就是密文中每行的第5個數,我們稱之為?神秘數?。 

密文中某些行的第五個數已經模糊不清,而這些數字正是揭開隕石秘密的鑰匙。現在科學家們聘請你來計算這個神秘數。 

思路:初始想法:我們令dp[l1][l2][l3][d]為用了l1個小括號,l2個中括號,l3個大括號,深度恰好為d時的方案數,現在我們來找狀態之間的聯絡。然而我們可以發現乙個殘酷的事實,光用4個變數無法很好的表示乙個狀態。比如,我們新增乙個小括號,當前狀態帶表的括號序列中,有一部分序列的深度增加了,有一部分沒有增加,所以為了正確的轉移狀態,正常想法就是用狀壓之類的記錄具體方案,然而這個題就。。。

我們可以發現,新新增乙個括號,括號序列的深度最多增加1,要麼就不變,所以,如果dp[l1][l2][l3][d]表示的是用了l1個小括號,l2個中括號,l3個大括號,深度小於等於d的方案數就很好辦了,新增乙個括號後從深度小於等於d的狀態轉移到深度小於等於d + 1的狀態。

則等於d的方案數 = 小於等於d的方案數 - 小於等於d - 1的方案數。

還有乙個問題,我們怎麼不重不漏的寫出狀態轉移的過程?我們可以發現,所有深度小於等於d的括號序列是由若干個深度小於等於d的巢狀的括號構成的,所以,我們可以這樣轉移狀態:我們把當前狀態分成2個部分,乙個部分用來形成巢狀的括號,另一部分對應的是那個狀態的方案數。我們列舉向最裡面新增什麼括號。因為大括號外面不能有其它的括號,所以當在最裡面套大括號時,只能有大括號。例如,當前巢狀形的括號是,我們不能向裡面新增{},但是新增小括號可以,變成。同理,列舉狀態時,當新增的是中括號時,外面只能是中括號和大括號。

思路和**實現參考了這篇部落格:

**:

#include #include #include #include using namespace std;

const int mod = 11380;

int dp[11][11][11][31];

bool v[11][11][11][31];

int dfs(int l1, int l2, int l3, int deep)

if (deep == 0)

if (v[l1][l2][l3][deep])

return dp[l1][l2][l3][deep];

int ans = 0;

for (int i = 0; i <= l3; i++)

for (int j = 0 ;j <= l2; j++)

for (int k = 1; k <= l1; k++)

} }v[l1][l2][l3][deep] = 1;

return dp[l1][l2][l3][deep] = ans;

}int main() else

}}

poj 1187 隕石的秘密

題目大意 求出指定要求的字串的種數,用dp a b c d 記錄有a個 b個,c個 深度為d的字串的個數,然後列舉左邊一段外層加括號的狀態,與右邊對應狀態相乘即可。include include include include include include include include incl...

POJ1187 隕石的秘密

題目大意 定義乙個串 只含有 3種 6個 字元。定義 ss 串 空串是ss表示式。若a是ss表示式,且a串中不含有中括號和大括號,則 a 是ss表示式。若a是ss表示式,且a串中不含有大括號,則 a 是ss表示式。若a是ss表示式,則是ss表示式。定義ss串深度 空串深度為0.若a可以寫成 a 其中...

題解 POJ1187 隕石的秘密

一開始很愉快地想到了乙個dp,然後發現ab c和a bc這兩種情況會重複計數。但其實在列舉a b型時,可以強制令a一定形如 c 這樣就可以避免重複計數了。include include includeusing namespace std const int mod 11380 int l1,l2,...