• bzoj 1079 [SCOI2008]着色方案


    bzoj 1079 [SCOI2008]着色方案

    Description

    有n个木块排成一行,从左到右依次编号为1~n。你有k种颜色的油漆,其中第i种颜色的油漆足够涂ci个木块。所有油漆刚好足够涂满所有木块,即c1+c2+...+ck=n。相邻两个木块涂相同色显得很难看,所以你希望统计任意两个相邻木块颜色不同的着色方案。

    Input

    第一行为一个正整数k,第二行包含k个整数c1, c2, ... , ck。

    Output

    输出一个整数,即方案总数模1,000,000,007的结果。

    Sample Input

    3
    
    1 2 3
    

    Sample Output

    10
    

    HINT

    100%的数据满足:1 <= k <= 15, 1 <= ci <= 5

    这道题有点玄学,不管了,开始我也没想到要这么做,讲一下大概做法吧.我们设f[a][b][c][d][e][last]为剩余涂色次数为1.2.3...5次的颜色数,last表示上次涂了剩余颜色数为last的颜色,举个例子,f[1][2][3][4][5][2]表示当前有1个颜色可以涂一次,两个颜色可以涂两次...上次涂的颜色是剩余涂色次数为2的颜色中的一个.那么我们可以想到这个状态可以由f[0][3][4][5][x]转移过来,那么我们就想到了可以dp了,由于对于剩余涂色次数为x的颜色,它们的性质是一样的,我们把它们加起来就可以了.于是我们可以打记忆化了.

    代码如下

    #include <cstdio>
    #include <algorithm>
    using namespace std;
    
    typedef long long LL;
    
    static const int maxm=15+1;
    static const int MOD=1e9+7;
    
    LL f[maxm][maxm][maxm][maxm][maxm][maxm];
    int cnt[maxm];
    int n,x;
    
    LL dfs(int a,int b,int c,int d,int e,int last){
        LL ret=0;
        if(!(a+b+c+d+e))return f[a][b][c][d][e][last]=1;
        if(f[a][b][c][d][e][last])return f[a][b][c][d][e][last];
        if(a)ret+=(a-(last==2))*dfs(a-1,b,c,d,e,1),ret%=MOD; //如果上次涂了剩余次数为2的颜色,那么它现在就转移到1的位置去了,所以要减一
        if(b)ret+=(b-(last==3))*dfs(a+1,b-1,c,d,e,2),ret%=MOD;
        if(c)ret+=(c-(last==4))*dfs(a,b+1,c-1,d,e,3),ret%=MOD;
        if(d)ret+=(d-(last==5))*dfs(a,b,c+1,d-1,e,4),ret%=MOD;
        if(e)ret+=e*dfs(a,b,c,d+1,e-1,5),ret%=MOD;
        return f[a][b][c][d][e][last]=ret;
    }
    
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d",&x),cnt[x]++;
    
        printf("%lld
    ",dfs(cnt[1],cnt[2],cnt[3],cnt[4],cnt[5],0));
        return 0;
    }
    

    点我进入AC通道

  • 相关阅读:
    Pyramid of Glasses 酒杯金字塔 [CF-676B]
    BZOJ 2456mode
    Hamburgers [CF-371C]
    lowbit
    two point
    大O表示法的理解
    6. 第 6 章 队列
    5. 第 5 章 栈
    3. 第 3 章 向量
    10. 第 10 章 指针
  • 原文地址:https://www.cnblogs.com/Exbilar/p/6701541.html
Copyright © 2020-2023  润新知