629. K个逆序对数组#
问题描述#
给出两个整数
n
和k
,找出所有包含从1
到n
的数字,且恰好拥有k
个逆序对的不同的数组的个数。逆序对的定义如下:对于数组的第
i
个和第j
个元素,如果满i
<j
且a[i]
>a[j]
,则其为一个逆序对;否则不是。由于答案可能很大,只需要返回 答案 mod 109 + 7 的值。
示例 1:
输入: n = 3, k = 0 输出: 1 解释: 只有数组 [1,2,3] 包含了从1到3的整数并且正好拥有 0 个逆序对。
示例 2:
输入: n = 3, k = 1 输出: 2 解释: 数组 [1,3,2] 和 [2,1,3] 都有 1 个逆序对。
说明:
n
的范围是 [1, 1000] 并且k
的范围是 [0, 1000]。
解题思路#
易知 \(n\) 个数按照 \(\boxed{n,n-1,\cdots,2,1}\) 的顺序排列时的逆序对最多,有 \((n-1)+(n-2)+\cdots+1=\frac{n\times(n-1)}{2}\) 个。
用 \(R(n)\) 表示 \(n\) 个数的最多逆序对数量,即 \(R(n)=\sum_{i=1}^{n-1}i=\frac{n\times n-1}{2}\)。
当从 \(n-1\) 个数变为 \(n\) 个数时,最多可以增加 \(n-1\) 个逆序对,因为 \(n-1\) 个数都比 \(n\) 小。
所以只要移动 \(n\) 在 \(n-1\) 个数中的位置,就可以最多增加 \(n-1\) 个逆序对。
用 \(P(n,k)=\{a_1^k,a_2^k,\cdots,a_n^k\}\) 表示 \(n\) 个数时逆序对为 \(k\) 的一个排列,\(k\le R(n)\)。
用 \(dp[n][k]\) 表示 \(n\) 个数中逆序对为 \(k\) 的排列数量。
\(P(n-1,k)=\{a_1^k,a_2^k,\cdots,a_{n-1}^k\}\),可以通过移动数字 \(n\) 在 \(P(n-1,k)\) 中的位置,来获得 \(n\) 的各个逆序对的数量。
所以
\(l=\max(0,j-(i-1)),r=\min(j,k,R(i-1))\)。
\(n=1,2,3\) 时各个逆序对的数量如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|