哎呀,這題太神奇了
設計狀態想爆腦袋都想不到什麼好的,感覺怎麼搞都o了個狀態總數,轉移就更別談了
一看題解,恍然大悟
哎呀。。
首先對ans=sigma(a[i]^2)
進行轉化,將其這樣理解:用a和
b分別表示一種取珠的方法,將結果相同的兩種取珠方法(不管這兩種取珠方法本身是否相同)記為
(a, b)
,不難發現ans
就是所有這樣的
(a, b)
的對數。
設狀態f(a1, b1, a2, b2)
,如果f(a1, b1, a2, b2) = k
,表示存在
k對不完全相同的
(a, b)
,使得a
方法已經取出了第乙個串的前
a1個字元及第二個串的前
b1個字元,
b方法已經取出了第乙個串的前
a2個字元以及第二個串的前
b2個字元,同時
a方法與
b方法得到的結果相同。
顯然,f(a1, b1, a2, b2)
可以轉移向
4個方向:
f(a1+1, b1, a2+1, b2)
,f(a1+1, b1, a2, b2+1)
,f(a1, b1+1, a2+1, b2)
,f(a1, b1+1, a2, b2+1)
,轉移可行的前提是對應的字母相同。
最後,f(n, m, n, m)
就是問題的答案。遞推初態是
f(0, 0, 0, 0) = 1.
恩,沒錯,就是這樣,就這麼簡單,可是就是沒想到啊
回過頭想想,本題中唯一能用的承受得起的表示狀態的東西就只有 操作序列
而怎麼用跟操作序列有關的狀態求出ans就成了本題關鍵,將乘法化為加法,對應到兩種操作序列上,平方運算自然消除,而且恰好造出了神奇演算法
**:
囧,這題想了好久。。
NOI2009 管道取珠
noi2009 管道取珠 給出乙個長度為n的01序列 和乙個長度為m的01序列 給出 n m 個格仔,按順序將a和b填入,也就是事先選好n個位置,按順序地填入a,然後其它的按順序填入b,設填後的格仔有 c 次重複,問所有的格仔填法 c 2 的和,n,m leq 500 平方可以轉換為兩個人填,方案相...
NOI2009 管道取珠
sum a i a i 可以理解為兩個獨立但同時進行的遊戲得到同乙個輸出序列的方案數。設f l,i,j 為每個遊戲都已經推出了l個珠子時,第乙個遊戲裡上邊兒的管道已經推出了i個,第二個遊戲中上邊兒管道推出了j個的方案數。考慮到若要推出序列相同,那麼對於每個階段l,兩個遊戲的推出序列應始終相等。這樣,...
NOI2009 管道取珠
對於處理方案數量平方的優化 可以看成兩個人玩同乙個遊戲,他們輸出序列一樣的種類數。然後設f i1 j1 i1 j2 為當前狀態方案數量的平方和。i1,i2表示第乙個人上管道,下管道分別取出了i1,i2個,i2,j2表示第二個人 i1 j1 i2 j2,所以可以把最後一維去掉。然後加乙個滾動陣列可以進...