Todo

Todo

打辅助.jpg

抢人头.jpg

抢不到我 当 场 把 键 盘 吃 掉 !

 

ABC134 F Permutation Oddness

每轮同时填格子和数,然后去绝对值。

 $f[i][j][k]$ 表示填了前 $i$ 个数和前 $i$ 个位置,空了 $j$ 个位置同时留了 $j$ 个数(我一开始还打算分两个状态来着),已填的部分产生的权为 $k$ 的方案数。

每次转移:

1.第 $i$ 个数填第 $i$ 个位置:空了 $j$ 个位置同时留了 $j$ 个数,产生权 $0$ ,方案数为 $1$;

2.第 $i$ 个数填前面空的格子,以前留的数填第 $i$ 个位置:空了 $j-1$ 个位置同时留了 $j-1$ 个数,产生权 $i+i$ ,方案数 $j^2$ ;

3.第 $i$ 个数填前面空的格子,第 $i$ 个位置留空:空了 $j$ 个位置同时留了 $j$ 个数,产生权 $i-i$ ,方案数为 $j$ ;

4.遗留第 $i$ 个数,以前留的数填第 $i$ 个位置:空了 $j$ 个位置同时留了 $j$ 个数,产生权 $-i+i$ ,方案数为 $j$ ;

5.遗留第 $i$ 个数,第 $i$ 个位置留空:空了 $j+1$ 个位置同时留了 $j+1$ 个数,产生权 $-i-i$ ,方案数 $1$ 。

#include<bits/stdc++.h>
using namespace std;
const int N=51;
const int Dl=2501;
const int P=1e9+7;

int f[N][N][2*N*N];

int main()
{
    int n,m,i,j,k;
    scanf("%d%d",&n,&m);
    f[0][0][Dl]=1;
    for(i=1;i<=n;i++)
        for(j=0;j<i;j++)
            for(k=-n*n;k<=n*n;k++){
                if(j&&k+2*i<=n*n)(f[i][j-1][k+2*i+Dl]+=1ll*f[i-1][j][k+Dl]*j*j%P)%=P;
                (f[i][j][k+Dl]+=1ll*f[i-1][j][k+Dl]*(2*j+1)%P)%=P;
                if(k-2*i>=-n*n)(f[i][j+1][k-2*i+Dl]+=f[i-1][j][k+Dl])%=P;
            }
    printf("%d",f[n][0][m+Dl]);
    return 0;
}
View Code

 

posted @ 2019-10-05 15:44  新时代中国特色OIer  阅读(346)  评论(2编辑  收藏  举报