description
現在有n個人要排成一列,編號為1->n 。但由於一些不明原因的關係,人與人之間可能存在一些矛盾關係,具體有m條矛盾關係(u,v),表示編號為u的人想要排在編號為v的人前面。要使得隊伍和諧,最多不能違背k條矛盾關係(即不能有超過k條矛盾關係(u,v),滿足最後v排在了u前面)。問有多少合法的排列。答案對10^9+7取模。
input format
輸入檔名為count.in。
第一行包括三個整數n,m,k。
接下來m行,每行兩個整數u,v,描述乙個矛盾關係(u,v)。
保證不存在兩對矛盾關係(u,v),(x,y),使得u=x且v=y 。
output format
輸出檔名為count.out。
輸出包括一行表示合法的排列數。
sample input
輸入1:
4 2 1
1 3
4 2輸入2:
10 12 3
2 6
6 10
1 7
4 1
6 1
2 4
7 6
1 4
10 4
10 9
5 9
8 10
sample output
輸出1:
18 輸出2:
123120
hint
對於30%的資料,n<=10
對於60%的資料,n<=15
對應100%的資料,n,k<=20,m<=n*(n-1),保證矛盾關係不重複。
f[i | (1 << j)][l + q] = (f[i | (1 << j)][l + q] + f[i][l]) % inf;
【考試時沒做幾題狀壓,沒想到先用二進位制壓每個人的矛盾關係,預處理超時了3個點【sto。
#include
using
namespace
std;
const
long
long inf = 1e9 + 7;
int n, m, k, i, j, l, q, u, v, head[25], g[25];
long
long f[1
<< 20][21], ans;
inline
int read()
while(ch >= '0' && ch <= '9')
x = x * 10 + ch - '0', ch = getchar();
return x * w;
} //讀入優化
inline
void write(long
long x)
//輸出優化
int main()
//讀入並壓位1.
f[0][0] = 1;
for(i = 0; i < 1
<< n; i ++)
for(j = 0; j < n; j ++)
if (! (i & (1
<< j)))
//狀壓dp 2.
ans = 0;
for(i = 0; i <= k; i ++)
ans = (ans + f[(1
<< n) - 1][i]) % inf;
write(ans);
//統計答案並輸出
return
0; }
給同學講壽司晚宴,用qq聊了好久 _ (:з」∠) _
期間手抖關了一次編輯器【當然沒儲存,於是碼到現在
要加快速度了!加油!!
狀壓DP cofun1623 壽司晚宴
輸入樣例1 3 10000 輸入樣例2 4 10000 輸入樣例3 100 100000000 sample output 樣例輸出1 9 樣例輸出2 21 樣例輸出3 做這題的時候看了dalao們的題解,感覺不是很能理解,還是自己打舒服 include using namespace std co...
狀壓dp 玉公尺田 狀壓dp
相關 強相關 327.玉公尺田 狀壓dp 小國王 狀壓dp 是井字形,本題是十字形。思路 狀態計算 時間複雜度 n 2 n 2n o n 22n 12 2 24n 2 n 2 n o n2 12 2 n 2n 2 n o n22n 12 224 看著妥妥超時,但是裡面合法狀態很少 依舊可以過 在此,...
狀壓dp小記
鋪磚 題意 現有nm的一塊地板,需要用12的磚塊去鋪滿,中間不能留有空隙。問這樣方案有多少種 include using namespace std typedef long long ll const int maxn 1 11 int n,m,state ll dp 15 maxn s1表示本行...