傳送門
首先我們發現乙個排列,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]*
∑if[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掉...