zoukankan      html  css  js  c++  java
  • (DP) bzoj 1079

    1079: [SCOI2008]着色方案

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 1068  Solved: 679
    [Submit][Status][Discuss]

    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]表示还剩1个格子的颜色有a种,剩2个格子的颜色有b种...依次类推。那么转移时

    f[a,b,c,d,e]=a*f[a-1,b,c,d,e]+b*f[a+1,b-1,c,d,e]+c*f[a,b+1,c-1,d,e]+...+e*f[a,b,c,d+1,e-1]

    可是我们发现没有考虑相邻的情况?没事!我们可以加一维!

    我们再加一维,表示上一次用的颜色是等价类last,那么这一次计算的时候因为不能相邻,那么这个这一次放last-1的颜色时要少一个,所以是a-1或b-1或....或e-1然后再乘上后边的f。

    那么转移就变成了:

    f[a,b,c,d,e,last]=(a-(last==2))*f[a-1,b,c,d,e]+(b-(last==3))*f[a+1,b-1,c,d,e]+(c-(last==4))*f[a,b+1,c-1,d,e]+...+(e-(last==6))*f[a,b,c,d+1,e-1]

    而last==6无意义,可以去掉。

    真的是好题啊啊啊啊

    #include<iostream>
    #include<cstdio>
    using namespace std;
    long long dp[16][16][16][16][16][7];
    int k,col[7];
    const int Mod=1000000007;
    long long dfs(int a,int b,int c,int d,int e,int k)
    {
        if(a+b+c+d+e==0)
            return 1;
        if(dp[a][b][c][d][e][k])
            return dp[a][b][c][d][e][k];
        long long temp=0;
        if(a)
            temp+=dfs(a-1,b,c,d,e,1)*(a-(k==2));
        if(b)
            temp+=dfs(a+1,b-1,c,d,e,2)*(b-(k==3));
        if(c)
            temp+=dfs(a,b+1,c-1,d,e,3)*(c-(k==4));
        if(d)
            temp+=dfs(a,b,c+1,d-1,e,4)*(d-(k==5));
        if(e)
            temp+=dfs(a,b,c,d+1,e-1,5)*e;
        return dp[a][b][c][d][e][k]=temp%Mod;
    
    }
    int main()
    {
        int x;
        scanf("%d",&k);
        for(int i=1;i<=k;i++)
        {
            scanf("%d",&x);
            col[x]++;
        }
        cout<<dfs(col[1],col[2],col[3],col[4],col[5],0)<<endl;
    }
    

      

  • 相关阅读:
    December 23rd 2016 Week 52nd Friday
    December 22nd 2016 Week 52nd Thursday
    December 21st 2016 Week 52nd Wednesday
    December 20th 2016 Week 52nd Tuesday
    December 19th 2016 Week 52nd Sunday
    December 18th 2016 Week 52nd Sunday
    uva294(唯一分解定理)
    uva11624Fire!(bfs)
    fzu2150Fire Game(双起点bfs)
    poj3276Face The Right Way
  • 原文地址:https://www.cnblogs.com/water-full/p/4515299.html
Copyright © 2011-2022 走看看