zoukankan      html  css  js  c++  java
  • [BZOJ 1079][SCOI 2008]着色方案

    1079: [SCOI2008]着色方案

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 2237  Solved: 1361
    [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

    题解

    令人恶心的一道 $DP$ ...

    注意到 $k$ 的范围很小, 所以首先我们可以想到的定义状态的方案是把每种油漆剩余的数量定义进状态, 但是 $15$ 维的记忆化数组怕是是个人都不想写吧...而且$5^{15}approx 3.05 imes 10^{10}$ 并不能开得下...

    但是我们会发现, 其实不同的油漆只要余量相等, 对于答案的影响并没有什么区别, 所以我们可以分别将余量为 $1,2,3,4,5$ 的油漆种数定义进状态, 再加一维表示上次用的是哪种油漆, $DFS$ 处理就好了

    代码挺好写, 但看起来比较恶心...

    参考代码

    GitHub

     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cstring>
     4 #include <iostream>
     5 #include <algorithm>
     6 
     7 const int MOD=1e9+7;
     8 const int MAXN=16;
     9 
    10 int n;
    11 int data[MAXN];
    12 int dp[MAXN][MAXN][MAXN][MAXN][MAXN][5];
    13 
    14 int DFS(int,int,int,int,int,int);
    15 
    16 int main(){
    17     scanf("%d",&n);
    18     int tmp;
    19     for(int i=0;i<n;i++){
    20         scanf("%d",&tmp);
    21         data[tmp]++;
    22     }
    23     for(int i=0;i<=5;i++){
    24         dp[0][0][0][0][0][i]=1;
    25     }
    26     printf("%d
    ",DFS(data[1],data[2],data[3],data[4],data[5],0));
    27     return 0;
    28 }
    29 
    30 int DFS(int r1,int r2,int r3,int r4,int r5,int last){
    31     if(dp[r1][r2][r3][r4][r5][last]!=0)
    32         return dp[r1][r2][r3][r4][r5][last];
    33     else{
    34         long long tmp=0;
    35         if(r1>0)
    36             tmp+=1ll*(last==2?r1-1:r1)*DFS(r1-1,r2,r3,r4,r5,1);
    37         if(r2>0)
    38             tmp+=1ll*(last==3?r2-1:r2)*DFS(r1+1,r2-1,r3,r4,r5,2);
    39         if(r3>0)
    40             tmp+=1ll*(last==4?r3-1:r3)*DFS(r1,r2+1,r3-1,r4,r5,3);
    41         if(r4>0)
    42             tmp+=1ll*(last==5?r4-1:r4)*DFS(r1,r2,r3+1,r4-1,r5,4);
    43         if(r5>0)
    44             tmp+=1ll*r5*DFS(r1,r2,r3,r4+1,r5-1,5);
    45         dp[r1][r2][r3][r4][r5][last]=tmp%MOD;
    46         return dp[r1][r2][r3][r4][r5][last];
    47     }
    48 }
    Backup

     

  • 相关阅读:
    dedecms织梦自定义表单发送到邮箱-用163邮箱发送邮件
    DedeCMS实现自定义表单提交后发送指定QQ邮箱法
    什么是授权码,它又是如何设置?
    telnet配置和telnet用法
    linux利用sendmail发送邮件的方法
    SSH会话连接超时问题
    dede 提交表单 发送邮件
    a 标签中 写页面刷新代码
    织梦dede在首页调用留言本
    PHP通过Thrift操作Hbase
  • 原文地址:https://www.cnblogs.com/rvalue/p/7684018.html
Copyright © 2011-2022 走看看