Description
Input
Output
Sample Input
10 1000
Sample Output
3628800
Data Constraint
Solution
一道比较简单的dp。
对于60%的数据
设
表示插入
这个数,逆序对个数为
的方案数。
那么插入
这个数所能产生的逆序对个数为
,
。很容易理解,因为你前面已经插入了1~i-1里的数,你插入在哪一个位置都行,比
小的数最少有0个,做多有
个。
对于100%的数据
到了这里还是不行,因为这道题的
,而这个算法是
的,所以我们还要考虑优化。
经过观察,发现
这个东西可以用前缀和维护,用前缀和优化后就可以把时间复杂度优化至
我比赛时忘记负数要加上模数了,爆成了70分,下次一定一定要注意。
还有一点要注意,记得要打滚动数组。
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
const ll mo=1e10+7;
int n,m;
ll ans,f[3005],sum[3005],s[3005];
int main() {
freopen("matryoshka.in","r",stdin);
freopen("matryoshka.out","w",stdout);
scanf("%d%d",&n,&m);
f[0]=1;
for(int i=0;i<=m;i++)sum[i]=1;
for(int i=2;i<=n;i++) {
s[0]=0;
for(int j=0;j<=m;j++) {
if(j-min(i-1,j)-1<0)f[j]=sum[j];
else f[j]=(sum[j]-sum[j-min(i-1,j)-1]+mo)%mo;
if(j>0)s[j]=(s[j-1]+f[j])%mo;
else s[j]=f[j];
}
for(int j=0;j<=m;j++)sum[j]=s[j];
}
printf("%lld",(sum[m]+mo)%mo);
fclose(stdin);
fclose(stdout);
return 0;
}