Jzoj P4271 魔法阵___组合数+dp

题目大意:

这里写图片描述

0 <= n <= 200 0 <= k <= m i n ( 200 , 8 n + 4 )

分析:

详见:
https://www.cnblogs.com/Comfortable/p/9301709.html

代码:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define fo(i, j, k) for (int i = j; i <= k; i++)
#define N 205

using namespace std;

typedef long long ll;

const int MOD = 1e9 + 7;

ll f[N][N][10], C[15][15];
int n, k;

int flag[10][10] = {
    {1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
    {1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
    {1, 0, 1, 0, 0, 0, 0, 0, 0, 0},
    {1, 2, 0, 1, 0, 0, 0, 0, 0, 0},
    {1, 2, 0, 0, 1, 0, 0, 0, 0, 0},
    {1, 1, 1, 0, 0, 1, 0, 0, 0, 0},
    {1, 0, 2, 0, 0, 0, 1, 0, 0, 0},
    {1, 3, 0, 2, 1, 0, 0, 1, 0, 0},
    {1, 2, 1, 1, 0, 2, 0, 0, 1, 0},
    {1, 4, 0, 4, 2, 0, 0, 4, 0, 1} }, 
    rp[10] = {12, 9, 6, 6, 6, 3, 0, 3, 0, 0},
    cp[10] = { 4, 2, 1, 1, 0, 0, 0, 0, 0, 0};

int main() {
    freopen("magic.in", "r", stdin);
    freopen("magic.out", "w", stdout);
    scanf("%d %d", &n, &k);
    fo (i, 0, 14) C[i][0] = 1;
    fo (i, 1, 14)
         fo(j, 1, i) C[i][j] = (C[i-1][j]+C[i-1][j-1])%MOD; 

    f[0][0][0] = 1,
    f[0][1][1] = 4, f[0][1][2] = 4;
    f[0][2][3] = 4, f[0][2][4] = 2, f[0][2][5] = 8, f[0][2][6] = 2;
    f[0][3][7] = 4, f[0][3][8] = 4;
    f[0][4][9] = 1;

    fo(i, 0, n-1)
        fo(j, 0, 9)
            fo(p, 0, k) if (f[i][p][j]) 
                fo(q, 0, 9) if(flag[j][q]) {
                    int left1 = rp[q], left2 = cp[q];
                    fo(r, 0, left2) { if (p+r > k) break;
                        fo(t, 0, left1-2*r) { if (p+r+t > k) break;
                            f[i+1][p+r+t][q] = (f[i+1][p+r+t][q]+(f[i][p][j]*C[left2][r])%MOD*C[left1-2*r][t]*flag[j][q]%MOD)%MOD;
                        }
                    }
                }

    ll ans = 0;
    fo(i, 0, 9) ans = (ans+f[n][k][i])%MOD;
    fo(i, 1, k) ans = ans*i%MOD;
    printf("%lld\n", ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/gx_man_vip/article/details/81021946
今日推荐