bzoj2431逆序对数列——递推

时间:2025-01-16 20:36:14

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2431

考虑新加入一个数i,根据放的位置不同,可以产生0~i-1个新逆序对;

所以f[i][j]可由f[i-1][j-k]相加得到,其中0<=k<=i-1&&k<=j;

再优化一下,每次前缀和减掉最前一个,加上最后一个,保持在合法范围内更新即可。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,m,sum;
int f[][],p=; int main(){
scanf("%d%d",&n,&m);
f[][]=;
/*
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
for(int k=0;k<i&&k<=j;k++)
(f[i][j]+=f[i-1][j-k])%=p;
*/
for (int i=;i<=n;i++){
sum=;
for (int j=;j<=m;j++){
if (j>=i)sum=(sum-f[i-][j-i]+p)%p;
(sum+=f[i-][j])%=p;
f[i][j]=sum;
}
}
printf("%d",f[n][m]);
return ;
}