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:

  1. The integer n is in the range [1, 1000] and k is in the range [0, 1000].

Approach #1: DP. [C++]

class Solution {
public:
int kInversePairs(int n, int k) {
vector<vector<int>> dp(n+1, vector<int>(k+1, 0));
dp[0][0] = 1;
for (int i = 1; i <= n; ++i) {
for (int j = 0; j < i; ++j) {
for (int m = 0; m <= k; ++m) {
if (m - j >= 0 && m - j <= k) {
dp[i][m] = (dp[i][m] + dp[i-1][m-j]) % mod;
}
}
}
}
return dp[n][k];
} private:
const int mod = pow(10, 9) + 7;
};

  

Analysis:

For example, if we have some permutation of 1 ..... 4

5 * * * * creates 4 new inverse pairs

* 5 * * * creates 3 new inverse pairs

* * 5 * * creates 2 new inverse pairs

* * * 5 * creates 1 new inverse pairs

* * * * 5 creates 0 new inverse pairs

We can use this formula to solve this problem

dp[i][j] : represent the number of permutations of (1 ... n) with k inverse pairs.

dp[i][j] = dp[i-1][j] + dp[i-1][j-1] + dp[i-1][j-2] + ..... + dp[i-1][j-i+1]

Approach #2 Optimization. [Java]

class Solution {
public int kInversePairs(int n, int k) {
int mod = 1000000007;
if (k > n*(n-1)/2 || k < 0) return 0;
if (k == 0 || k == n*(n-1)/2) return 1;
long[][] dp = new long[n+1][k+1];
dp[2][0] = 1;
dp[2][1] = 1;
for (int i = 3; i <= n; i++) {
dp[i][0] = 1;
for (int j = 1; j <= Math.min(k, i*(i-1)/2); j++) {
dp[i][j] = dp[i][j-1] + dp[i-1][j];
if (j >= i) dp[i][j] -= dp[i-1][j-i];
dp[i][j] = (dp[i][j] + mod) % mod;
}
}
return (int)dp[n][k];
}
}

  

Analysis:

Look back to the above formula.

dp[i][j] = dp[i-1][j] + dp[i-1][j-1] + dp[i-1][j-2] + ..... +dp[i-1][j - i + 1]

Let's consider this example

if i = 5:

dp[i][0] = dp[i-1][0] (creates 0 inverse pair)
dp[i][1] = dp[i-1][0] (1) + dp[i-1][1] (0) = dp[i][0] + dp[i-1][1]
dp[i][2] = dp[i-1][0] (2) + dp[i-1][1] (1) + dp[i-1][2] (0) = dp[i][1] + dp[i-1][2]
.
.
.
dp[i][4] = dp[i-1][0] (4) + dp[i-1][1] (3) + dp[i-1][2] (2) + dp[i-1][3] (1) + dp[i-1][4] (0) = dp[i][3] + dp[i-1][4]

We can find the rules about above formula.

if j < i, we can compute dp[i][j] = dp[i][j-1] + dp[i-1][j]

So how about j >= i

We know if we add number i into permutation(0 .. i-1), i can create 0 ~ i-1 inverse pair.

If j >= i, we still use dp[i][j] = dp[i][j-1] + dp[i-1][j].

We must minus dp[i][j-1]. (In fact it minus dp[i-1][j-1], because every j >= i in dp array, it minus dp[i-1][j-i] individually)

For example, if i = 5

dp[i][5] = dp[i][4] + dp[i-1][5] - dp[i-1][0]
dp[i][6] = dp[i][5] + dp[i-1][6] - dp[i-1][1]

Reference:

https://leetcode.com/problems/k-inverse-pairs-array/discuss/104815/Java-DP-O(nk)-solution

https://leetcode.com/problems/k-inverse-pairs-array/discuss/104825/Shared-my-C%2B%2B-O(n-*-k)-solution-with-explanation

629. K Inverse Pairs Array的更多相关文章

  1. 【leetcode dp】629. K Inverse Pairs Array

    https://leetcode.com/problems/k-inverse-pairs-array/description/ [题意] 给定n和k,求正好有k个逆序对的长度为n的序列有多少个,0& ...

  2. [LeetCode] K Inverse Pairs Array K个翻转对数组

    Given two integers n and k, find how many different arrays consist of numbers from 1 to n such that ...

  3. [Swift]LeetCode629. K个逆序对数组 | K Inverse Pairs Array

    Given two integers n and k, find how many different arrays consist of numbers from 1 to n such that ...

  4. [leetcode-629-K Inverse Pairs Array]

    Given two integers n and k, find how many different arrays consist of numbers from 1 to n such that ...

  5. Java实现 LeetCode 629 K个逆序对数组(动态规划+数学)

    629. K个逆序对数组 给出两个整数 n 和 k,找出所有包含从 1 到 n 的数字,且恰好拥有 k 个逆序对的不同的数组的个数. 逆序对的定义如下:对于数组的第i个和第 j个元素,如果满i < ...

  6. Find the largest K numbers from array (找出数组中最大的K个值)

    Recently i was doing some study on algorithms. A classic problem is to find the K largest(smallest) ...

  7. 23.Merge k Sorted Lists (Array, Queue; Sort)

    Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 思 ...

  8. Leetcode 629.K个逆序对数组

    K个逆序对数组 给出两个整数 n 和 k,找出所有包含从 1 到 n 的数字,且恰好拥有 k 个逆序对的不同的数组的个数. 逆序对的定义如下:对于数组的第i个和第 j个元素,如果满i < j且  ...

  9. LeetCode All in One题解汇总(持续更新中...)

    突然很想刷刷题,LeetCode是一个不错的选择,忽略了输入输出,更好的突出了算法,省去了不少时间. dalao们发现了任何错误,或是代码无法通过,或是有更好的解法,或是有任何疑问和建议的话,可以在对 ...

随机推荐

  1. 分析maven的优点

    1.依赖管理: 就是对jar包的管理. 2.项目的一键构建: 编译--->测试--->运行--->打包--->安装 运行一个maven工程(web工程)只需要一个命令:toma ...

  2. 证书吊销列表(CRL)介绍

    一.证书吊销列表(CRL) 证书吊销列表 (Certificate Revocation List ,简称: CRL) 是 PKI 系统中的一个结构化数据文件,该文件包含了证书颁发机构 (CA) 已经 ...

  3. 教你用PS修复老照片

    原图素材虽然很旧,不过人物部分并没有怎么损坏,只是有一些色块和杂色.修复的工程相对来说也少很多.只需要给人物磨好皮,然后把暗调和高光部分调出来即可.原图     一.打开原图素材,按Ctrl + J ...

  4. Laravel图表扩展包推荐:Charts

     2016年11月15日 ·  2283次 ·  4条 ·  laravel,package,charts 介绍 在项目开发中,创建图表通常是一件痛苦的事情.因为你必须将数据转换为图表库支持的格式传输 ...

  5. [Selenium]如何实现上传本地文件

    public void uploadLocalFileToServer(String uploadFileName){ String AutomationPath = System.getProper ...

  6. wpf 进度条 下拉

    <Window x:Class="WpfApplication1.MainWindow"        xmlns="http://schemas.microsof ...

  7. 7.25 js 自定义方法 a.b

    调用: $(function(){ Starinput.initiate({name:'qr1_z.startlevel',tar: $("#sitelogo1"), stars: ...

  8. Picard Tools

    Picard Tools - By Broad Institute http://broadinstitute.github.io/picard/command-line-overview.html ...

  9. 2018.10.23 hdu4745Two Rabbits(区间dp)

    传送门 区间dp经典题目. 首先断环为链. 然后题目相当于就是在找最大的回文子序列. 注意两个位置重合的时候相当于范围是n,不重合时范围是n-1. 代码: #include<bits/stdc+ ...

  10. python调用dll方法

    在python中调用dll文件中的接口比较简单,实例代码如下: 如我们有一个test.dll文件,内部定义如下: extern "C"{ int __stdcall test( v ...