老网站文章突然无收录,线上代运营公司,手机站和微网站的区别,好看的 网站后台模板给出两个整数 n 和 k#xff0c;找出所有包含从 1 到 n 的数字#xff0c;且恰好拥有 k 个逆序对的不同的数组的个数。
逆序对的定义如下#xff1a;对于数组的第i个和第 j个元素#xff0c;如果满i j且 a[i] a[j]#xff0c;则其为一个逆序对#xff1b;否则…给出两个整数 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]。
来源力扣LeetCode 链接https://leetcode-cn.com/problems/k-inverse-pairs-array 著作权归领扣网络所有。商业转载请联系官方授权非商业转载请注明出处。
解题报告
经典动态规划。dp[i][j]代表1~i可以构成逆序对为k的方案数。
考虑转移dp[i][j]即最后一步决策即在1~i-1已经放好的基础上i放到哪个位置上放到不同的位置上可以新增0~i-1中的某个值。当然也不能超了j。即更新dp[i][j]时决策第i层可以新层逆序对的个数0~min(i-1, j)。对应加和就行。然后用前缀和优化一下。空间也可以滚动数组优化但是没啥必要了就不写了。
AC代码
class Solution {
public:long long dp[1005][1005];long long sum[1005];const int mod 1e9 7;int kInversePairs(int n, int k) {dp[0][0] 0;for(int i 1; in; i) dp[i][0] 1;for(int i 1; in; i) {sum[0] dp[i-1][0];for(int j 1; jk; j) {sum[j] (sum[j-1] dp[i-1][j])%mod;}for(int j 1; jk; j) {int down min(i-1,j);dp[i][j] (sum[j] - (j-down-10?sum[j-down-1]:0) mod) % mod;}}return dp[n][k] % mod;}
};
TLE代码
class Solution {
public:long long dp[1005][1005];const int mod 1e9 7;int kInversePairs(int n, int k) {dp[0][0] 0;for(int i 1; in; i) dp[i][0] 1;for(int i 1; in; i) {for(int j 1; jk; j) {for(int q 0; qi-1; q) {if(j-q 0) break;dp[i][j] dp[i-1][j-q];dp[i][j] % mod;}}}// for(int i 0; in; i) {// for(int j 0; jk; j) {// cout dp[i][j] ;// }// cout endl;// } return dp[n][k] % mod;}
};