XSY3952 簡單的計數題(dp)

2021-10-22 08:32:19 字數 2408 閱讀 3892

簡單的計數題

首先題意可以轉化為:給你乙個長度為 n

nn 的序列 c

cc,求將 c

cc 分成兩個長度為 n

2\dfrac

2n​ 的相同的子串行的方案數。

考慮 dp,設 f(i

,sta

)f(i,sta)

f(i,st

a)表示已經將 c

cc 的前 i

ii 位分成了兩個子串行,其中長的子串行比短的子串行多出來的未匹配的部分為 sta

stast

a(用dequelist等stl容器均可記錄)的方案數。不妨稱這個 sta

stast

a 為狀態,那麼只有當狀態長度不大於 n

2\dfrac

2n​ 時,這個狀態才是有用的。

轉移十分簡單:新加入乙個元素時,考慮是繼續扔到當前狀態的尾部,還是和當前狀態的開頭匹配並刪除這個開頭。

這裡主要講為什麼時間是對的:

時間複雜度和狀態數有關。假設當前到第 i

ii 位,一共有 x

xx 個狀態,考慮接下來的 c

cc 的兩個元素 a,b

a,ba,

b:於是此時總狀態不超過 3n2

3^}32

n​種。但還是太多了。

由於我們只需要知道 f(n

,∅

)f(n,\empty)

f(n,∅)

,所以考慮折半:將 c

cc 序列的前一半和後一半(要翻轉)分別 dp,最後將前後兩半的 dp 值合併起來統計答案。

此時狀態數不超過 3n4

3^}34

n​種。然後題解說進一步分析(?)可以證明在 n=60

n=60

n=60

時狀態數不超過 50000

50000

50000。

**如下:

#include

#define n 65

using

namespace std;

namespace modular

inline

intdec

(int x,

int y)

inline

intmul

(int x,

int y)

}using

namespace modular;

inline

intread()

while

(ch>=

'0'&&ch<=

'9')

return x*f;

}typedef deque<

int> sta;

int t,n,hn,a[n];

sta now1,now2;

mapint>dp[2]

[n>>1]

;void

solve

(bool opt)

now2=now1;

now2.

push_back

(a[i+1]

);if(

!now1.

empty()

) dp[opt]

[i+1

][now2]

=add

(dp[opt]

[i+1

][now2]

,dp[opt]

[i][now1]);

else dp[opt]

[i+1

][now2]

=add

(dp[opt]

[i+1

][now2]

,mul

(dp[opt]

[i][now1],2

));}

}}intmain()

if(!now2.

empty()

) ans=

add(ans,

mul(

(*it)

.second,

mul(dp[1]

[hn]

[now2]

,inv2)))

;else ans=

add(ans,

mul(

(*it)

.second,dp[1]

[hn]

[now2]))

;}printf

("%d\n"

,ans);}

return0;

}/*52

1 12

2 24

1 1 2 2

61 2 3 4 5 6

41 2 2 1

*/

實測dequelist快,我直接疑惑了。

XSY3156 簡單計數II 容斥 DP

定義乙個序列的權值為 把所有相鄰的相同的數合併為乙個集合後,所有集合的大小的乘積。特別的,第乙個數和最後乙個數是相鄰的。現在你有 n 種數,第 i 種有 c i 個。求所有不同的序列的權值的和。n leq 50,c i leq 100 考慮第乙個數和最後乙個數不相鄰時怎麼做。記 g 為出現了 i 次...

666RPG 計數dp簡單題

lililalala正在玩一種有 n n個回合的回合制rpg遊戲,初始分數為0,第 i i個回合lililalala有如下兩種選擇。a.將分數加上 ai ai b.將分數 1 1 lililalala同樣也很討厭野獸數 666 666,但是他很卻喜歡數字 666 666。他想知道有多少種不同的方案使...

poj 幾道簡單的dp題

題意 求使數列程先遞增後遞減的形式需要去掉的數字個數。當然也可以直接遞減或者只遞減不遞增。分析 用最長遞增子串行的方法求,然後列舉兩個起點的位置即可。include include include using namespace std const int inf 1e8 const int n 1...