zoukankan      html  css  js  c++  java
  • bzoj1079[SCOI2008]着色方案

    题目链接

    bzoj1079[SCOI2008]着色方案

    题解

    状态设计好神呐
    dp[a][b][c][d][e][last]
    表示剩余1个的有a中,2个的有b中三个的有c中....
    last表示上次转移的种类
    然后记忆化搜索一下
    乘法原理转移

    代码

    #include<cstdio>
    #include<algorithm>
    inline int read () {
        int x = 0,f = 1;
        char c = getchar();
        while(c <= '0' || c > '9') {if(c == '-')f = -1;c = getchar();} 
        while(c <= '9' && c >= '0') x = x * 10 + c - '0',c = getchar();
        return x * f;
    }
    #define LL long long
    const int mod = 1e9 + 7;
    const int maxn = 19;
    LL dp[maxn][maxn][maxn][maxn][maxn][7];
    LL dfs(int a,int b,int c,int d,int e,int last) { //last 安放改点的等价类与上次等价类变化后相同,减掉
        if(!a && !b && !c && !d && !e) return 1;
        if(dp[a][b][c][d][e][last]) return dp[a][b][c][d][e][last]; 
        LL ret = 0;
        if(a) ret +=dfs(a - 1,b,c,d,e,1) * (a - (last == 2)) ;
        ret %= mod;
        if(b) ret +=dfs(a + 1,b - 1,c,d,e,2) * (b - (last == 3)) ;
        ret %= mod;
        if(c) ret +=dfs(a ,b + 1,c - 1,d,e,3) * (c - (last == 4)) ;
        ret %= mod;
        if(d) ret +=dfs(a,b,c + 1,d - 1,e,4) * (d - (last == 5)) ;
        ret %= mod; 
        if(e) ret +=dfs(a,b,c,d + 1,e - 1,5) * e ;// 上次等价类已经转移纸last - 1
        ret %= mod;
        return dp[a][b][c][d][e][last] = ret;
    }
    int C[maxn];
    int main() {
           int n = read();	
        for(int i = 1;i <= n ;++ i)  C[read()] ++; 
        printf("%lld
    ",dfs(C[1],C[2],C[3],C[4],C[5],0) % mod);
        return 0;
    }
    
    
  • 相关阅读:
    AcWing 1081. 度的数量
    CF584D Dima and Lisa
    [ABC130F] Minimum Bounding Box
    AT4289 [ABC133E] Virus Tree 2
    Arc of Dream HDU
    Reading comprehension HDU
    【洛谷 1541】乌龟棋
    【洛谷 4880】抓住czx
    【洛谷 1525】关押罪犯
    【洛谷 1040】加分二叉树
  • 原文地址:https://www.cnblogs.com/sssy/p/8869922.html
Copyright © 2011-2022 走看看