Given two integers n and k, find how many different arrays consist of numbers from 1 to n such that there are exactly k inverse pairs.
We define an inverse pair as following: For ith and jth element in the array, if i < j and a[i] > a[j] then it’s an inverse pair; Otherwise, it’s not.
Since the answer may be very large, the answer should be modulo 109 + 7.
Example 1:
Input: n = 3, k = 0
Output: 1
Explanation:
Only the array [1,2,3] which consists of numbers from 1 to 3 has exactly 0 inverse pair.
Example 2:
Input: n = 3, k = 1
Output: 2
Explanation:
The array [1,3,2] and [2,1,3] have exactly 1 inverse pair.
Note:
The integer n is in the range [1, 1000] and k is in the range [0, 1000].
给出n和k,问有多少种排列方式可以使1~n的数中正好有k个降序对
思路:
0个数中有0个降序对的排列数是1
1~n的数如果是按升序排列,那么就是0个降序对,所以1~n的数中k=0的排列数也是1
剩下的,比如n=3, 数字是1,2,3,加入4的话可以有
[4,1,2,3], 在1,2,3的基础上增加3个降序对
[1,4,2,3], 在1,2,3的基础上增加2个降序对
[1,2,4,3], 在1,2,3的基础上增加1个降序对
[1,2,3,4], 在1,2,3的基础上增加0个降序对
所以在[1,2,3]的基础上增加4,可以增加0+1+2+3个降序对
定义dp[n][k],表示1~n的数字有k个降序对的排列数
所以dp[n][k] = dp[n-1][k] + dp[n-1][k-1] + dp[n-1][k-2] + … + dp[n-1][k-n+1] (1)
再简化一下
取k+1
dp[n][k+1] = dp[n-1][k+1] + dp[n-1][k] + dp[n-1][k-1] + … + dp[n-1][k-n+2] (2)
(2)式 - (1)式错位相消,得到
dp[n][k+1] - dp[n][k] = dp[n-1][k+1] - dp[n-1][k-n+1]
把k+1换成k,得到
dp[n][k] = dp[n][k-1] + dp[n-1][k] - dp[n-1][k-n]
其中最后一项只有在k >= n时才计算
注意,因为有减法,而且结果要取模,为了防止出现负数,减法时要+mod再取模
public int kInversePairs(int n, int k) {
int mod = 1000000007;
int[][] dp = new int[n+1][k+1];
dp[0][0] = 1;
for(int i = 1; i <= n; i++) {
dp[i][0] = 1;
for(int m = 1; m <= k; m ++) {
dp[i][m] = (dp[i][m-1] + dp[i-1][m]) % mod;
if(m >= i) {
dp[i][m] = (dp[i][m] - dp[i-1][m-i] + mod) % mod;
}
}
}
return dp[n][k];
}