想破脑袋也想不到。。。。
先定义状态,dp[i][j]表示i个数字的全排列中逆序数为j的序列的个数
刚开始做的时候,拿笔画了一会,凭着感觉蒙了个状态转移方程:dp[i][j]=dp[i-1][j]+dp[i][j-1]+dp[i-1][j-1],试了下果然蒙的不可靠。。就去看讨论了,找到正解。。
#include <cstdio>
#include <cstring>
int dp[1010][20010];
int n,k;
const int mod = 1e9+7;
void init()
{
int t1,t2,t3;
for(int i = 1; i < 1010; ++i)
{
dp[i][0] = 1;
for(int j = 1; j <= i*(i-1)/2 && j < 20010; ++j)
{
t1 = t2 = t3 = 0;
t1 = dp[i][j-1];
t2 = dp[i-1][j];
if(j >= i)
t3 = dp[i-1][j-i];
dp[i][j] = ((t1+t2-t3)%mod+mod)%mod;
}
}
}
int main()
{
init();
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d %d",&n,&k);
printf("%d\n",dp[n][k]);
}
return 0;
}