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 there are exactly kinverse 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].

解题思路:

假设dp[n][k]为1-n个数字组成的数组中逆序为k的数组个数。

那么当dp[n-1][k]时,n应放位置如下:

x1 , x2 , x3 ,..........,xn-1, n

当dp[n-1][k - 1]时,n应放位置为:

x1,x2,x3,..........,xn-2,n,xn-1    增加n,xn-1这一对逆序;

依次类推 : 将n放在x1前面时最多能增加n-1对逆序 ;

所以

当k>=n时

dp[n][k] = dp[n-1][k] + dp[n-1][k-1]+....+dp[n-1][k-n+1];

dp[n][k-1] = dp[n-1][k-1] + dp[n-1][k-2] +......+ dp[n-1][k-n];

所以dp[n][k] = dp[n-1][k] + dp[n][k-1] - dp[n-1][k-n];

当k<n时:

dp[n][k] = dp[n-1][k] + dp[n-1][k-1]+....+dp[n-1][0];

dp[n][k-1] = dp[n-1][k-1] + dp[n-1][k-2] + dp[n-1][0];

所以dp[n][k] = dp[n-1][k] + dp[n][k-1] ;

class Solution {
public:
    int kInversePairs(int n, int k) {
        
        vector<vector<int>> dp(n + 1 , vector<int>(k + 1 , 0)) ;
        for(int i = 0 ; i <= n ; ++i) dp[i][0] = 1 ;
        int mod = 1000000007 ;
        
        for(int i = 1 ; i<= n ; ++i)
            for(int j = 1 ; j<= k ; ++j)
            {
                dp[i][j] = (dp[i - 1][j] + dp[i][j - 1])% mod ;
                if(j >= i) dp[i][j] = (dp[i][j] - dp[i - 1][j - i] + mod)%mod ;
            }
        
        //cout<<dp[3][0]<<endl;
        
        return dp[n][k] ;
    }
};

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值