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. aspx导出文件

    System.IO.StringWriter sw = new System.IO.StringWriter(); HtmlTextWriter htw = new HtmlTextWriter(sw ...

  2. 在cygwin中执行bat文件

    在cygwin中执行bat文件 #!/bin/bash dir_gen_image_bat=C:/MinGW/msys/1.0/home/Administrator/feitian_audio/FOT ...

  3. part1:2-嵌入式系统简单概念

    1.3个特点+1个性质:以应用为中心.软硬件可裁剪.对功能-体积-功耗等有严格要求:专用的计算机系统. 应用领域: 软硬件可裁剪,是什么结构让嵌入式系统具备了这样的特点? 嵌入式系统的体系结构:硬件: ...

  4. android textview settext卡顿深层次原因

    最近在公司项目里面发现listview里面的textview在调用settext函数的时候非常耗时,当时都有点不敢相信,这是因为如果你把textview设置成wrap_content,则每次调用set ...

  5. 全球晶圆代工厂哪家强?2016年Top30名单

    1.台积电(TSMC) 总部:台湾 简介:世界上最大的独立半导体晶圆代工企业,与联华电子并称“晶圆双雄”. 主要客户:苹果,高通,联发科,华为海思 官网:http://www.tsmc.com/ 2. ...

  6. sqlserver 清除日志

    要使用Master数据库执行 DUMP TRANSACTION 数据库名 WITH NO_LOG 2.再打开企业管理器--右键你要压缩的数据库--所有任务--收缩数据库--收缩文件--选择日志文件-- ...

  7. Redis为什么是单线程

    转自:https://www.zhihu.com/question/23162208 https://www.zhihu.com/question/55818031:加了一些个人的理解. Redis为 ...

  8. python网页爬虫 spiders_97A-04B

    import urllib import urllib.request import bs4 from bs4 import BeautifulSoup as bs import re import ...

  9. golang闭包里的坑

    介绍 go的闭包是一个很有用的东西.但是如果你不了解闭包是如何工作的,那么他也会给你带来一堆的bug.这里我会拿出Go In Action这本书的一部分代码,来说一说在使用闭包的时候可能遇到的坑.全部 ...

  10. Oracle实现递归查询

    前几天在开发的过程中遇到一个递归查询的问题,java代码大致是这样的: // 递归得到四级机构对象 public UserManagerDept getuserManagerDeptBy(String ...