C++ 中 K 逆序对数组


假设我们有两个整数 n 和 k,我们需要找到有多少个不同的数组由 1 到 n 的数字组成,并且正好有 k 个逆序对。对于数组中的第 i 个和第 j 个元素,如果 i < j 且 a[i] > a[j],则称为逆序对。这里答案可能非常大,答案应该模 $10^{9}$ + 7。

因此,如果输入类似于 n = 3 和 k = 1,则输出将为 2,因为数组 [1,3,2] 和 [2,1,3] 将只有一个逆序对。

为了解决这个问题,我们将遵循以下步骤:

  • 定义一个大小为 (n + 1) x (k + 1) 的二维数组 dp
  • dp[0, 0] := 1
  • 初始化 i := 1,当 i<= n 时,更新(i 增加 1),执行:
    • dp[i, 0] := 1
    • 初始化 j := 1,当 j <= k 时,更新(j 增加 1),执行:
      • dp[i, j] := dp[i, j - 1] + dp[i – 1, j]
      • dp[i, j] := dp[i, j] mod m
      • 如果 j >= i,则:
        • dp[i, j] := (dp[i, j] - dp[i – 1, j - i] + m) mod m
  • 返回 dp[n, k]

让我们看看下面的实现,以便更好地理解:

示例

 在线演示

#include <bits/stdc++.h>
using namespace std;
const int m = 1e9 + 7;
class Solution {
public:
   int kInversePairs(int n, int k) {
      vector < vector <int> > dp(n + 1, vector <int>(k + 1));
      dp[0][0] = 1;
      for(int i = 1; i <= n; i++){
         dp[i][0] = 1;
         for(int j = 1; j <= k; j++){
            dp[i][j] = dp[i][j - 1] + dp[i - 1][j];
            dp[i][j] %= m;
            if(j >= i){
               dp[i][j] = (dp[i][j] - dp[i - 1][j - i] + m) % m;
            }
         }
      }
      return dp[n][k];
   }
};
main(){
   Solution ob;
   cout << (ob.kInversePairs(4,2));
}

输入

4
2

输出

5

更新于: 2020-06-01

226 次浏览

开启你的 职业生涯

通过完成课程获得认证

开始学习
广告