【动规】逆序对为k的排列个数
k inverse pairs array
给出两个整数
n
和k
,找出所有包含从1
到n
的数字,且恰好拥有k
个逆序对的不同的数组的个数。
令
假设我们知道
展开可发现:
从而:
边界条件:
动态规划:
class Solution {
public:
const static int M = 1e9 + 7;
int kInversePairs(int n, int k) {
vector<vector<long long>> dp(n+1, vector<long long>(k+1, 0));
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= k; j++) {
if (j == 0) dp[i][j] = 1;
else if (i == 1) dp[i][j] = 0;
else {
dp[i][j] = (dp[i-1][j] + dp[i][j-1]) % M;
if (j - i >= 0) dp[i][j] = (dp[i][j] - dp[i-1][j-i] + M) % M;
}
}
}
return dp[n][k];
}
};
空间优化:
class Solution {
public:
static const int mod = 1000000007;
int kInversePairs(int n, int k) {
int f[2][k + 1];
memset(f, 0, sizeof(f));
f[1][0] = 1;
for (int i = 2; i <= n; ++i) {
int flip = i & 1;
int sum = 0;
for (int j = 0; j <= k; ++j) {
sum += f[1 - flip][j];
if (j >= i) sum -= f[1 - flip][j - i];
if (sum < 0) sum += mod;
if (sum >= mod) sum -= mod;
f[flip][j] = sum;
}
}
return f[n & 1][k];
}
};