您的位置:首页 > 大数据 > 人工智能

629. K Inverse Pairs【Hard】 动态规划

2017-09-21 16:28 99 查看
作死试了一个看起来比较简单的HARD题,刚开始看到题目还觉得有点思路,然而后来却发现没法降低时间复杂度。

我的思路如下:每次知道了第n个状态下所有k的情况(即知道所有a[1,2..n][k]),则n+1的情况便可求出来。

  因为从n到n+1是相当于在原来的1,2..n的无序序列中加入n+1这个数,那么这个数,n+1,可以放置的位置有n+1位,

  例如n=4时,n+1=5,加入5的情况有    

    xxxx5  k+=0

    xxx5x  k+=1

    xx5xx  k+=2

    x5xxx  k+=3

    5xxxx  k+=4

  <n,k>下有a
[k]个序列,那么就相当于给<n+1, k+i> (i=0,1,2,3,4)都贡献了a
[k]个序列

  相当于给a[n+1][k] ,  a[n+1][k+1] , a[n+1][k+2] , a[n+1][k+3] , a[n+1][k+4]都加上了a
[k]

  所以循环n次之后就能知道a
[k]的值了

#include <iostream>
using namespace std;
const int md = 1000000007;
int a[1001][1001] = {{0}}, n, j, i, x, k;

int main() {
cin >> n >> k;

for (i = 1; i <= n; ++i) {
if (i == 1) a[i][0] = 1;
else for (j = 0; a[i - 1][j] > 0 && j <= k; ++j)
for (x = 0; x < i && j + x <= k; ++x) {
a[i][j + x] += a[i - 1][j];
a[i][j + x] %= md;
}
}

cout << a
[k];

return 0;
}


看了网上的博客才知道这题可以用类似求等比数列的办法来算每个<n,k>的值,降低了复杂度,优化了算法。

原因是:由前面的推导,可以知道:

    a
[k] = a[n - 1][k] + a[n - 1][k - 1] + ... + a[n - 1][k - n + 1]

用k-1替换k,就能得到:

    a
[k - 1] = a[n - 1][k - 1] + a[n - 1][k - 2] + ... + a[n - 1][k - n]

一式减去二式,得到:

    a
[k] = a
[k - 1] + a[n - 1][k] - a[n - 1][k - n]

    当k>=n的时候,a[n - 1][k - n]才会有意义,所以要判断一下k和n的关系,如果k>=n的话,就要减去最后一项

这个递推式减少了一个循环,使算法更高效,代码如下:

class Solution {
public:
int kInversePairs(int n, int k) {
const int md = 1000000007;
int a[1001][1001] = {{0}};
int j, i;

a[0][0] = 1;
for (i = 1; i <= n; ++i) {
a[i][0] = 1;
for (j = 1; j <= k; ++j) {
a[i][j] = (a[i - 1][j] + a[i][j - 1]) % md;
if (j >= i) {
a[i][j] = (a[i][j] - a[i - 1][j - i] + md) % md;
}
}
}
return a
[k];
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: