JZOJ 4318. 【NOIP2015模拟11.5】俄罗斯套娃

题目大意

求逆序对个数小于等于 \(k\) 的排列数

解析

已经做过很多次了,经典得不能再经典的问题
注意本题很卡空间,要用滚动数组

\(Code\)

#include<cstdio>
using namespace std;
typedef long long LL;

const int N = 3005;
const LL P = 1e10 + 7;
int n , k;
LL f[3][N] , sum[N] , ans;

int main()
{
	freopen("matryoshka.in" , "r" , stdin);
	freopen("matryoshka.out" , "w" , stdout);
	scanf("%d%d" , &n , &k);
	f[1][0] = 1;
	for(register int i = 2; i <= n; i++)
		for(register int j = 0; j <= k; j++)
		{
			if (j == 0) sum[j] = f[(i & 1) ^ 1][j];
			else sum[j] = (sum[j - 1] + f[(i & 1) ^ 1][j]) % P;
			if (j >= i) f[i & 1][j] = ((sum[j] - sum[j - i]) % P + P) % P;
			else f[i & 1][j] = sum[j];
		}
	for(register int i = 0; i <= k; i++) ans = (ans + f[n & 1][i]) % P;
	printf("%lld" , ans);
}
posted @ 2020-08-05 14:59  leiyuanze  阅读(87)  评论(0编辑  收藏  举报