原题链接:统计上升四元组
动态规划:
其中f[i][j]f[i][j]代表的是截止到当前下标为ii的数组下,大于等于jj的个数,维护的话也是非常简单的一个线性dpdp,可知f[i][j]=f[i1][j]f[i][j] = f[i-1][j]当前下标下大于等于jj的个数是大于等于下标为i1i-1状态下大于等于jj的个数的。如果nums[i]jnums[i] \ge j那么很明显f[i][j]f[i][j]要在f[i1][j]f[i-1][j]的基础上加1。
维护好f[i][j]f[i][j]之后的工作就很简单了,枚举中间两个逆序,假设下标为j,kj,k那么我们分别要寻找:
x1x1:下标不超过jj且小于nums[j]nums[j]的个数
x2x2:下标超过kk且大于nums[i]nums[i]的个数
CPP代码如下

class Solution {
public:
    #define ll long long 
    int idx = 0;

int f[4010][4010];
long long countQuadruplets(vector<int>& nums) {
    int len = nums.size();
    int n = len;
    len-=1;
    //f[i][j] 大于等于j的个数
    for(int i=nums[0];i>=0;--i)f[0][i] = 1;
    for(int i=1;i<=len;++i){
        for(int j=0;j<=n;++j){
            f[i][j] = f[i-1][j];
            if(nums[i] >= j)f[i][j]++;
        }
    }
    ll ans = 0;
    for(int i=1;i<len;++i){
        for(int j=i+1;j<len;++j){
            if(nums[i] < nums[j]){
                continue;
            }
            int x1 = i+1-f[i][nums[j]];
            int x2 = n-nums[i]+1-f[j][nums[i]];
            ll res =(ll) x1 * x2;
            ans += res ;
        }
    }
    return ans ;
}
};