计算K反向对的数量时C ++溢出

时间:2017-08-05 07:45:44

标签: c++ algorithm dynamic-programming integer-overflow

给定两个整数n和k,我想计算有多少个不同的数组由1到n的数字组成,这样就有正好k个逆对。 (即,对i,j使i<ja[i]>a[j])Mod 10 ^ 9 + 7。

我正在使用动态编程,我将DP[i][j]定义为具有i个元素且具有正好j反转的数组的数量,然后我导出了重复:

DP[i][j]=DP[i-1][j]+dp[i-1][j-1]+...+dp[i-1][j-i+1]

另外,我注意到了:

DP[i][j-1]=DP[i-1][j-1]+DP[i-1][j-2]+...+DP[i-1][j-i]

因此,结合两个总和,我们得到:

DP[i][j]=DP[i-1][j]+DP[i][j-1]-DP[i-1][j-i]

我编写了以下动态编程解决方案,该解决方案适用于大n直到n,k大约为800.但是,一旦我传递了这些值(例如,n = 1000,k = 990),结果就会溢出而我不是确定为什么会这样。这是我的解决方案:

class Solution {
public:
    long long MOD = 1e9+7;
    int kInversePairs(int n, int k) {
        vector< vector<long long> > dp(1001, vector<long long>(1001, -1));
        return solve(dp, n, k);
    }
    long long solve(vector< vector<long long> >& dp, int n, int k){
        if (k<0)return 0;
        if (k==0)return 1;
        if (n==0)return 0;
        if (dp[n][k]!=-1)return dp[n][k];
        dp[n][k]=solve(dp, n-1, k)%MOD;
        dp[n][k]+=solve(dp, n, k-1)%MOD;
        dp[n][k]-=solve(dp, n-1, k-n)%MOD;
        //if (dp[n][k]<0){
        //    cout << "Overflow: " << solve(dp, n-1, k-n) << " " << solve(dp, n-1, k) <<  " " << solve(dp, n, k-1) << endl;
        //}
        return dp[n][k]%=MOD;
    }
};

1 个答案:

答案 0 :(得分:2)

我最终想出了答案。我在这里添加完成。

dp[n][k]-=solve(dp, n-1, k-n)%MOD;行之后,有可能dp [n] [k]小于零,因为我们每时每刻都采用模MOD,所以即使dp [n]的实际值[ k]在此行之前是1e20,我们采用模MOD,因此其值可能会降至零。所以在这一行之后,该值可能是负数。

我解决这个问题的方法是在取最后一个模之前添加+ MOD。这是工作代码:

class Solution {
public:
    long long MOD = 1e9+7;
    int kInversePairs(int n, int k) {
        vector< vector<long long> > dp(1001, vector<long long>(1001, -1));
        return solve(dp, n, k);
    }
    long long solve(vector< vector<long long> >& dp, int n, int k){
        if (k<0)return 0;
        if (k==0)return 1;
        if (n==0)return 0;
        if (dp[n][k]!=-1)return dp[n][k];
        dp[n][k]=solve(dp, n-1, k)%MOD;
        dp[n][k]+=solve(dp, n, k-1)%MOD;
        dp[n][k]-=solve(dp, n-1, k-n)%MOD;
        dp[n][k]+=MOD; //just in case it became negative 
        return dp[n][k]%=MOD;
    }
};