俄罗斯套娃
Description
Input
Output
Sample Input
10 1000
Sample Output
3628800
Data Constraint
反思&题解
比赛思路: 暴力枚举全排列判断
正解思路: 设
表示考虑了前i个数,逆序对为j的排列数,易得方程为:
,又因为求的是连续一段的和,所以我们预处理一下前缀和就可以将复杂度优化到
(还有这题空间极其恶心,要开滚动数组)
反思: 比赛的时候状态设得有问题,所以一直推不出来,对于DP的感觉还是要多练
CODE
#include<bits/stdc++.h>
using namespace std;
const long long mo=10000000007;
long long f[2][3005],n,k,sum[3005];
int main()
{
freopen("matryoshka.in","r",stdin);
freopen("matryoshka.out","w",stdout);
scanf("%lld%lld",&n,&k);
long long i,j,x=1;
for (i=0;i<=k;i++)
sum[i]=1;
f[0][0]=1;
for (i=1;i<=n;i++)
{
for (j=0;j<=min(k,i*(i-1)/2);j++)
{
if (j-i+1>0) f[x][j]=(sum[min(j,(i-1)*(i-2)/2)]-(sum[j-i])+mo)%mo;
else f[x][j]=sum[min(j,(i-1)*(i-2)/2)];
}
for (j=0;j<=k;j++)
{
sum[j]=0;
f[x^1][j]=0;
}
sum[0]=f[x][0];
for (j=1;j<=k;j++)
sum[j]=(sum[j-1]+f[x][j])%mo;
x^=1;
}
printf("%lld\n",sum[k]);
return 0;
}