原题链接:统计上升四元组
动态规划:
其中代表的是截止到当前下标为的数组下,大于等于的个数,维护的话也是非常简单的一个线性,可知当前下标下大于等于的个数是大于等于下标为状态下大于等于的个数的。如果那么很明显要在的基础上加1。
维护好之后的工作就很简单了,枚举中间两个逆序,假设下标为那么我们分别要寻找:
下标不超过且小于的个数
下标超过且大于的个数
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 ;
}
};