Atcoder ABC180 F Unbranched dp 组合数学 (无代码)

题目链接

题意:
n n n个点 m m m条边的点有编号边无编号的满足以下条件的无向图个数:
1. 1. 1.不必是简单图或连通图
2. 2. 2.每个点度数最多是 2 2 2
3. 3. 3.最大连通块的大小恰好是 l l l

2 < = n < = 200 , 1 < = m , l < = n 2<=n<=200,1<=m,l<=n 2<=n<=200,1<=m,l<=n
1 e 9 + 7 1e9+7 1e9+7

题解:
首先注意思考图的本质不同。首先要注意到你给一个连通块选的点的顺序不同,但是点的集合是一样的,这两种方案是相同的。

然后考虑这题最特别的一点要求,就是每个点的度数最多是 2 2 2,那么说明这个图的每一个连通块要么是一条链(包括单独一个点),要么是一个环。

我们很容易考虑一个状态: d p [ i ] [ j ] dp[i][j] dp[i][j]表示选了 i i i个点,有 j j j条边的方案数。但是这样有一个问题,就是我们不能很好的限制最大连通块大小恰好是 l l l。可能可以用一维 0 / 1 0/1 0/1来记录这个状态是否选过大小是 l l l的块来做。但是标算的做法是用一个简单的容斥思想:用最大块大小最多是 l l l的答案减去最大块大小最多是 l − 1 l-1 l1的答案。

这样我们想清楚怎么计算答案之后,就该考虑如何转移dp了。我们用分类讨论的办法考虑dp的转移。

这里首先说这题最关键的地方,也是我记录这题的主要原因,就是这里的计数需要先强制当前编号最小的没选过的点一定要选,尽管我们并不关心它具体是哪个点。这里关键问题是,不做这个强制直接乘组合数的话,会出现重复。举个例子:会出现先选1、2再选3、4和先选3、4再选1、2会被重复计算。当时我的一个想法是从小到大考虑块的大小,然后一次把相同大小的块一起考虑来更新答案,再除一个阶乘,但是答案还是不对,暂时没想好是写挂了还是数得就不对。

先讲正解做法,考虑转移。

1.加入一个单独的点,这个点形成一个新的连通块。
d p [ i ] [ j ] + = d p [ i − 1 ] [ j − 1 ] dp[i][j]+=dp[i-1][j-1] dp[i][j]+=dp[i1][j1]

2.加入一条长度为 k k k的链( 2 < = k < = l 2<=k<=l 2<=k<=l)。注意到链上的点可以随意排列,但是在图的意义下把一个排列翻转和原排列是等价的,所以要除 2 2 2。因为强制选编号最小的没选的点,于是组合数那里要减 1 1 1
d p [ i ] [ j ] + = d p [ i − k ] [ j − k + 1 ] ∗ C n − ( i − k ) − 1 k − 1 ∗ k ! 2 dp[i][j]+=dp[i-k][j-k+1]*C_{n-(i-k)-1}^{k-1}*\frac{k!}{2} dp[i][j]+=dp[ik][jk+1]Cn(ik)1k12k!

3.加入一个大小为 2 2 2的环
d p [ i ] [ j ] + = d p [ i − 2 ] [ j − 2 ] ∗ C n − ( i − 2 ) − 1 2 − 1 dp[i][j]+=dp[i-2][j-2]*C_{n-(i-2)-1}^{2-1} dp[i][j]+=dp[i2][j2]Cn(i2)121

4.加入一个大小为 k k k的环( k > 2 k>2 k>2)。注意到环排列的公式是 ( n − 1 ) ! (n-1)! (n1)!
d p [ i ] [ j ] + = d p [ i − k ] [ j − k ] ∗ C n − ( i − k ) − 1 k − 1 ∗ ( k − 1 ) ! 2 dp[i][j]+=dp[i-k][j-k]*C_{n-(i-k)-1}^{k-1}*\frac{(k-1)!}{2} dp[i][j]+=dp[ik][jk]Cn(ik)1k12(k1)!

这样就做完了,复杂度 O ( n ∗ k ∗ l ) O(n*k*l) O(nkl)

代码暂时没有。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值