BZOJ4498 魔法的碰撞(組合數學 dp)

2021-09-25 06:01:48 字數 2024 閱讀 4465

傳送門

首先我們發現乙個排列,2個魔法使之間一定要填max

(di,

di+1

)−

1max(d_i,d_)-1

max(di

​,di

+1​)

−1個格仔而如果總共一定要填的為k

kk個,貢獻就是(l−

kn)(n

l−k​

)考慮dpdp

dp出每種情況的方案數

首先按d

dd從大到小排序消除max

maxma

x我們發現乙個魔法師的貢獻只和他左右2邊的人比他大還是小

我們考慮記一維還有幾個比已經算的人要小的需要填的

考慮f [i

][j]

[k

]f[i][j][k]

f[i][j

][k]

表示前i

ii個人,前面人還需要填入j

jj個比他們小的,總貢獻為k

kk的方案數

考慮轉移只需要列舉當前這個要0,1

,2

0,1,2

0,1,

2個比他小的就可以了

最後答案就是∑if

[n][

0][i

]∗(l

−in)

\sum_f[n][0][i]*

∑i​f[n

][0]

[i]∗

(nl−

i​)

#include

using

namespace std;

const

int rlen=

1<<20|

1;inline

chargc(

)#define gc getchar

inline

intread()

#define ll long long

#define pii pair

#define pb push_back

#define re register

const

int mod=

1e9+7;

inline

intadd

(int a,

int b)

inline

void

add(

int&a,

int b)

inline

intdec

(int a,

int b)

inline

void

dec(

int&a,

int b)

inline

intmul

(int a,

int b)

inline

void

mul(

int&a,

int b)

inline

intksm

(int a,

int b,

int res=1)

const

int n=

44,m=

1000005

;int l,n,d[n]

,s,fac[m]

,ifac[m]

,f[n]

[n][

2*n*n]

;inline

void

init()

inline

intc

(int n,

int m)

inline

bool

comp

(int a,

int b)

intmain()

}int res=0;

for(

int i=

0;i<=

2*s;i++

)add

(res,

mul(f[n][0

][i],c

(l-i,n)))

; cout<}

BZOJ 4498 魔法的碰撞

魔法總是令戰鬥的局面變幻莫測。然而魔力的碰撞則更是天馬行空,甚至會出現無法控制而自取滅亡的情況。因此,魔力碰撞總是沒有辦法的辦法。設想有一條長度為l的戰線,你可以把你的魔法師們安排在戰線上的每個格仔。每乙個魔法師都有乙個攻擊範圍di,排兵時必須保證任意兩個魔法師的攻擊範圍的較大值小於等於它們之間的距...

BZOJ4498 魔法的碰撞 DP

我們先考慮全部緊湊的情況,也就是沒有多餘的空格的情況 將d id i di 先不考慮魔法師佔的空間 這裡用了乙個很巧妙的方法,多加一維,表示預留的空位。加入a會有三種情況 e表示空位 a,ae或ea,eae。對於第一種,表示a兩邊都有魔法師。對於第二種,表示a的一邊有,一邊沒有。對於第三種,表示a的...

BZOJ4498 魔法的碰撞(動態規劃)

點此看題面 大致題意 你要在 m 個格仔中擺放 n 個魔法師 每個魔法師有乙個攻擊範圍 使他們不能互相攻擊,求方案數。要用魔法戰勝魔法!顯然我不會魔法只會膜法,所以就被這道題吊錘了 這是一道比較有趣的題。題意看起來很簡單,資料範圍好像也很小,於是我就先後飛快地有了兩個想法,然後又先後飛快地hack掉...