給出兩個整數 n 和 k,找出所有包含從 1 到 n 的數字,且恰好擁有 k 個逆序對的不同的陣列的個數。
逆序對的定義如下:對於陣列的第i個和第 j個元素,如果滿i < j且 a[i] > a[j],則其為乙個逆序對;否則不是。
由於答案可能很大,只需要返回 答案 mod 109 + 7 的值。
示例 1:
輸入: n = 3, k = 0
輸出: 1
解釋:只有陣列 [1,2,3] 包含了從1到3的整數並且正好擁有 0 個逆序對。
示例 2:
輸入: n = 3, k = 1
輸出: 2
解釋:陣列 [1,3,2] 和 [2,1,3] 都有 1 個逆序對。
說明:n 的範圍是 [1, 1000] 並且 k 的範圍是 [0, 1000]。
網上的** 32ms
class solution
}else}}
return dp[n][k];
}};
定義dp[n][k]表示從1到n構成的數中含有k個逆序對的個數,則我們可以推導出dp[n][k]和dp[n - 1][i]之間的遞推關係:
如果我們把n放在最後一位,則所有的k個逆序對均來自於前n - 1個數所構成的逆序對,和n無關;
如果我們把n放在倒數第二位,則有1個逆序對和n有關,有k - 1個逆序對來自前n - 1個數所構成的逆序對;
如果我們把n放在第一位,則有n-1個逆序對和n有關,k - (n - 1)個逆序對來自前n - 1個數所構成的逆序對。
所以:dp[n][k] = dp[n-1][k]+dp[n-1][k-1]+dp[n-1][k-2]+…+dp[n-1][k+1-n+1]+dp[n-1][k-n+1]。但問題是 k - (n - 1)有可能為負數,也就是說根據n和k的不同,上面的式子有可能從某個項之後就不合法了,我們這裡先寫出來佔位,從而得到下面兩個式子:
dp[n][k] = dp[n-1][k]+dp[n-1][k-1]+dp[n-1][k-2]+…+dp[n-1][k+1-n+1]+dp[n-1][k-n+1]
dp[n][k+1] = dp[n-1][k+1]+dp[n-1][k]+dp[n-1][k-1]+dp[n-1][k-2]+…+dp[n-1][k+1-n+1]
把上面兩個式子相減可以推導出:dp[n][k+1] = dp[n][k]+dp[n-1][k+1]-dp[n-1][k+1-n]。這樣就可以寫出**了。
當然由於dp[n][k]只和dp[n][x],dp[n-1][x]有關,所以該**還可以進一步將空間複雜度從o(nk)降低到o(k)。時間複雜度是o(nk)。
629 K個逆序對陣列
題目描述 給出兩個整數 n 和 k,找出所有包含從 1 到 n 的數字,且恰好擁有 k 個逆序對的不同的陣列的個數。逆序對的定義如下 對於陣列的第i個和第 j個元素,如果滿i j且 a i a j 則其為乙個逆序對 否則不是。由於答案可能很大,只需要返回 答案 mod 109 7 的值。解題思路 思...
629 K個逆序對陣列
題目描述 給出兩個整數 n 和 k,找出所有包含從 1 到 n 的數字,且恰好擁有 k 個逆序對的不同的陣列的個數。逆序對的定義如下 對於陣列的第i個和第 j個元素,如果滿i j且 a i a j 則其為乙個逆序對 否則不是。由於答案可能很大,只需要返回 答案 mod 109 7 的值。示例 1 輸...
629 K個逆序對陣列
給出兩個整數 n 和 k,找出所有包含從 1 到 n 的數字,且恰好擁有 k 個逆序對的不同的陣列的個數。逆序對的定義如下 對於陣列的第i個和第 j個元素,如果滿i j且 a i a j 則其為乙個逆序對 否則不是。由於答案可能很大,只需要返回 答案 mod 109 7 的值。import j a....