[ABC134F] Permutation Oddness

· · 题解

[ABC134F] Permutation Oddness

题面翻译

定义一个 1 \sim n 的排列 p 的「怪异度」为

\sum_{i=1}^n|p_i-i|

求「怪异度」为 k1 \sim n 的排列数,答案对 10^9+7 取模。

题解

妙妙的 DP 题,其实最难的是转化和状态设置,方程很好推。

1. 问题转化

粘了一下题面,看着清楚些

考虑转化题目,把题目中的 p_ii 表示成球和盒子,球在左边摆一列,盒子在右边摆一列。如果 p_i=x,把左边的第 i 个球和右边的第 x 个盒子连起来。

如:若 p_{114514}=1919810,把左边的第 114514 个球和右边的第 1919810 个盒子连线。

这样我们就把一个排列转化为了一个匹配数为 n 的二分图。

现在一共有 n 行,第 i 行的第一个是球,第二个是盒子,在两行之间作一根黑直线。发现每根红线(球和盒子的连线)经过的黑线数量的总和就是怪异度。

如样例 \lbrace 2,1,3 \rbrace,指 p_1=2,p_2=1,p_3=3,化为下图:

画得丑见谅 看不懂算了

## 2. 状态设置 那这样肯定用 DP 做。 设状态 $f_{i,j,k}$ 表示前 $i$ 行,有 $j$ 组**球和盒子**没有被连线(用二分图想,这里的意思是本来应该有 $i$ 个匹配,但是只有 $i-j$ 个,剩了 $j$ 个球和 $j$ 个盒子还没有匹配),然后当前的奇异度是 $k$ 的方案数。 那么答案就是 $f_{n,0,k}$(这里 $k$ 是它输入的第二个数),表示前 $n$ 个数,匹配完了,相当于未匹配数是 $0$ ,奇异度是 $k$ 的方案数。 都看到这里了,是不是点个赞的说。 ## 3. 状态转移 我们 $f_{i,j,k}$ 的方案数与 $f_{i-1,anything,anything}$ 的差距只在于第 $i$ 排的盒子和球的选择方案。可以根据这个来分类讨论,因为第 $i$ 排有两个物体,最多匹配两组,所以分类讨论匹配 $0,1,2$ 组的方案数。 #### 1. 只匹配一组 - 把第 $i$ 个球向前 $i-1$ 个盒子中未被连线的盒子连一条线,且第 $i$ 个盒子不动它的方案数,即为 $j \times f_{i-1,j,k-2j}$(乘了一个 $j$ 是因为可以选择没被选的 $j$ 个盒子中的任意一个,第二维是因为这次连了 $1$ 条边,$i$ 也多了 $1$,抵消了;第三维和下面的第三维都后面再解释,先看完分类)。 - 把第 $i$ 个盒子向前 $i-1$ 个球中未被连线的球连一条线,且第 $i$ 个球不动它的方案数,即为 $j \times f_{i-1,j,k-2j}$ (乘了一个 $j$ 是因为可以选择没被选的 $j$ 个球中的任意一个,第二维是因为这次连了 $1$ 条边,$i$ 也多了 $1$,抵消了)。 - 自己连自己的情况:单独讨论,显然是 $f_{i-1,j,k-2j}$。 #### 2. 匹配两组 - 由于要匹配两组,第 $i$ 个球和第 $i$ 个盒子显然就不能互相选了,所以选前面没被选过的就行,即 $(j+1)^2 \times f_{i-1,j+1,k-2j}$(第二维的 $j+1$,因为这次连了 $2$ 条边,$i$ 却只增加了 $1$,前面的 $(j+1)^2$ 意思就是第 $i$ 个球能选前面未被选的 $j+1$ 个盒子,第 $i$ 个盒子同理,然后这样连边是互不干扰的,所以用乘法乘起来)。 #### 3. 不匹配 - 直接就是 $f_{i-1,j+1,k-2j}$(第二维因为边数增加了 $0$, $i$ 却增加了 $1$)。 --- 综上所述: $$f_{i,j,k}=j \times f_{i-1,j,k-2j}+j \times f_{i-1,j,k-2j}+f_{i-1,j,k-2j}+(j+1)^2 \times f_{i-1,j+1,k-2j}+f_{i-1,j+1,k-2j}$$ 合并同类项: $$f_{i,j,k}=(2j+1) \times f_{i-1,j,k-2j}+(j+1)^2 \times f_{i-1,j+1,k-2j}+f_{i-1,j+1,k-2j}$$ ## 4. 第三维转移的解释 比如现在有 $f_{i,j,k}$,这里的 $j$ 也有另一种表示:有 $j$ 个球和 $j$ 个盒子要连线到 $i+1 \sim n$ 中去了。 因为最后一定是有 $n$ 个匹配,这 $j$ 个球和 $j$ 个盒子又不往 $1 \sim i$ 中的元素连,那就只能往后面连了。 那么这些球和盒子连的对象行数每多 $1$,就多经过 $1$ 根黑线,奇异度就多 $1$。 本来它们是有可能连到第 $i$ 行的,结果我们把这行的连接确定了,它们的连线对象就只好整体向下移动一行了,这 $j$ 个球和 $j$ 个盒子就让奇异度多了 $j+j=2j$,算回去就是 $k-2j$。 ## 5. AC Code ```cpp #include<bits/stdc++.h> #define int long long #define N 59 using namespace std; const int mod=1e9+7; int n,magic,f[N][N][N*N]; signed main(){ ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); cin>>n>>magic; f[0][0][0]=1; for(int i=1;i<=n;i++){ for(int j=0;j<=i;j++){ for(int k=j*2;k<=magic;k++){ if(j>=1){ f[i][j][k]=(f[i-1][j-1][k-j*2]+f[i-1][j][k-j*2]*(j*2+1)%mod+f[i-1][j+1][k-j*2]*(j+1)%mod*(j+1)%mod)%mod; } else f[i][j][k]=(f[i-1][j][k-j*2]*(j*2+1)%mod+f[i-1][j+1][k-j*2]*(j+1)%mod*(j+1)%mod)%mod; } } } cout<<f[n][0][magic]; return 0; } ```