JZOJ 5230 隊伍統計 狀壓dp

2021-09-10 07:07:27 字數 2223 閱讀 2580

現在有n個人要排成一列,編號為1->n 。但由於一些不明原因的關係,人與人之間可能存在一些矛盾關係,具體有m條矛盾關係(u,v),表示編號為u的人想要排在編號為v的人前面。要使得隊伍和諧,最多不能違背k條矛盾關係(即不能有超過k條矛盾關係(u,v),滿足最後v排在了u前面)。問有多少合法的排列。答案對10^9+7取模。

有1~n個小學生排隊搶宵夜,由於一些f**k原因,m條矛盾關係(u,v),表示編號為u的小學生想要排在編號為v的人前面否則打架,不能使k隊小學生打架,求合法序列的方案數mod 1e9+7

第一行包括三個整數n,m,p。

接下來m行,每行兩個整數u,v,描述乙個矛盾關係(u,v)。

保證不存在兩對矛盾關係(u,v),(x,y),使得u=x且v=y 。

輸出包括一行表示合法的排列數。

對於30%的資料,n<=10

對於60%的資料,n<=15

對應100%的資料,n,k<=20,m<=n*(n-1),保證矛盾關係不重複。

in

10 12 3

2 66 10

1 74 1

6 12 4

7 61 4

10 4

10 9

5 98 10

out

123120
30%

暴力dfs,全排列然後計算方案數

60%暴力加剪枝

100%

狀壓dp,即狀態壓縮動態規劃

faq:

從何看出?

對應100%的資料,n,k<=20,m<=n*(n-1),保證矛盾關係不重複。

所以我們可以通過列舉 2

n2^n

2n次來壓縮1~n個小學生選還是不選的情況

通俗地講,設1≤i

≤2n1\leq i\leq 2^n

1≤i≤2n

所以設 fi,

jf_fi,j

​ 為 i

ii這個狀態下,已經有j

jj對小學生打架的方案數總和

那麼就有 f[i][j] 轉移到f[i or 2k−

12^2k−1

][j+tot](前提是k這個人並不在i這個狀態內並且j+tot≤

\leq

≤p)k表示這時候如果加進來乙個人k,tot表示加進來k後會多幾個小學生打架

那麼就有轉移方程

dp完了

答案就是

上**tips:in c++,__builtin_popcount(x)可快速計算x的二進位制下有多少個1

有關c++__builtin_popcount(x)的用法戳

兄dei,不是c++的快轉吧,**s*al會錯的

#include #define ll long long

#define cnt(x) __builtin_popcount(x)//定義cnt(x)等價於__builtin_popcount(x)

#define mod (int)(1e9+7)

#define open(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout);

using namespace std;

ll n,m,k,f[1<<20][30],g[1<<20][30],fal[50],cnt[1<<20],ans=0,max=0;

int main()

f[0][0]=1;max=(1<

for(int i=0;i

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

if(f[i][j])

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

}for(int i=0;i<=k;++i)(ans+=f[max-1][i])%=mod;

printf("%lld",ans);

return 0;

}

jzoj5230 隊伍統計 狀壓dp

n nn個人排隊,m mm個條件 u,v u,v u,v 表示u uu要排在v vv前,可以去掉k kk個,求方案總數 考慮依次插入人在隊頭 對於狀態1表示已經在佇列裡,0表示不在 f i,jf fi,j 表示i ii表示狀態,j jj表示違背了的條件個數。然後列舉隊頭的是哪個人,計算出插入他前的狀...

Jzoj5230 隊伍統計

現在有n個人要排成一列,編號為1 n 但由於一些不明原因的關係,人與人之間可能存在一些矛盾關係,具體有m條矛盾關係 u,v 表示編號為u的人想要排在編號為v的人前面。要使得隊伍和諧,最多不能違背k條矛盾關係 即不能有超過k條矛盾關係 u,v 滿足最後v排在了u前面 問有多少合法的排列。答案對10 9...

jzoj 5230 隊伍統計 狀態壓縮DP

description 現在有n個人要排成一列,編號為1 n 但由於一些不明原因的關係,人與人之間可能存在一些矛盾關係,具體有m條矛盾關係 u,v 表示編號為u的人想要排在編號為v的人前面。要使得隊伍和諧,最多不能違背k條矛盾關係 即不能有超過k條矛盾關係 u,v 滿足最後v排在了u前面 問有多少合...