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与记忆化搜索结合在了一起……
  我们做一个假设,假设ci都为1,那么这就是一道状压题了,但是ci<=5,虽然仍然不大,但是状压15位显然扑街。
  让我们回过头在看最基础的暴力,也就是我们去枚举每一位放的颜色,并将它传递给下一层dfs,如果我们分析一下的话我们会发现每一种剩下可涂数量相同的颜色都可以看作等价的,换句话说涂谁都行。那么,我们将状压的方式换一换,不对,不能叫状压了。改为ci剩余1 2 3 4 5 个的颜色有几种,上一个是谁,也就是f[15][15][15][15][15][7]。空间没问题,至于转移,我们利用dfs的思想,使用记忆化搜索,然后对于每一个f,假设当前状态为f[a][b][c][d][e][la]
  则若d!=0且la!=3那么f[a][b][c][d][e][la]+=f[a][b][c][d-1][e+1][2]*d。
  若la=3那么f[a][b][c][d][e][la]+=(d-1)*f[a][b][c][d-1][e+1][2]。
  其余同理。
  不得不说转移数组挺像一道概率DP“抵制克苏恩”的,可惜没有能够应用到这道题来啊。
 #include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <cmath>
#include <map>
using namespace std;
int n,t,a[],js[];
long long f[][][][][][],p=;
bool vi[][][][][][];
long long dfs(int a,int b,int c,int d,int e,int la)
{
     
    if(a==&&b==&&c==&&d==&&e==)return ;
    if(vi[a][b][c][d][e][la])return f[a][b][c][d][e][la];
    vi[a][b][c][d][e][la]=;
    if(a)f[a][b][c][d][e][la]+=a*dfs(a-,b+,c,d,e,),f[a][b][c][d][e][la]%=p;
    if(b)
    {
        if(b!=)f[a][b][c][d][e][la]+=(b-(la==))*dfs(a,b-,c+,d,e,);
        else if(la!=)f[a][b][c][d][e][la]+=dfs(a,b-,c+,d,e,);
        f[a][b][c][d][e][la]%=p;
    }
    if(c)
    {
        //cout<<a<<' '<<b<<' '<<c<<' '<<d<<' '<<e<<endl;
        if(c!=)f[a][b][c][d][e][la]+=(c-(la==))*dfs(a,b,c-,d+,e,);
        else if(la!=) f[a][b][c][d][e][la]+=dfs(a,b,c-,d+,e,);
        f[a][b][c][d][e][la]%=p;
    }
    if(d)
    {
         
        if(d!=)f[a][b][c][d][e][la]+=(d-(la==))*dfs(a,b,c,d-,e+,);
        else if(la!=)f[a][b][c][d][e][la]+=dfs(a,b,c,d-,e+,);
        f[a][b][c][d][e][la]%=p;
    }
    if(e)
    {
        if(e!=)f[a][b][c][d][e][la]+=(e-(la==))*dfs(a,b,c,d,e-,);
        else if(la!=)f[a][b][c][d][e][la]+=dfs(a,b,c,d,e-,);
        f[a][b][c][d][e][la]%=p;
    }
    return f[a][b][c][d][e][la];
}
int main()
{
    scanf("%d",&t);
    for(int i=;i<=t;i++)
    {
        scanf("%d",&a[i]);
        n+=a[i];
        js[a[i]]++;
    }
    long long ans=dfs(js[],js[],js[],js[],js[],);
    printf("%lld\n",ans);
    return ;
}

  顺便提一句,我之所以还要多开一个vi数组,是为了防止f模p之后为0的情况。

Bzoj 1079 着色方案 题解的更多相关文章

  1. [BZOJ]1079 着色方案(SCOI2008)

    相邻色块不同的着色方案,似乎这道题已经见过3个版本了. Description 有n个木块排成一行,从左到右依次编号为1~n.你有k种颜色的油漆,其中第i种颜色的油漆足够涂ci个木块.所有油漆刚好足够 ...

  2. bzoj 1079 着色方案

    题目: 有n个木块排成一行,从左到右依次编号为1~n.你有k种颜色的油漆,其 中第i 种颜色的油漆足够涂ci 个木块.所有油漆刚好足够涂满所有木块,即c1+c2+-+ck=n.相邻两个木块涂相同色显得 ...

  3. BZOJ 1079 着色方案(DP)

    如果把当前格子涂什么颜色当做转移的话,状态则是每个格子的颜色数还剩多少,以及上一步用了什么颜色,这样的状态量显然是5^15.不可取. 如果把当前格子涂颜色数还剩几个的颜色作为转移的话,状态则是每个格子 ...

  4. BZOJ 1079: [SCOI2008]着色方案 记忆化搜索

    1079: [SCOI2008]着色方案 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/p ...

  5. BZOJ 1079: [SCOI2008]着色方案(巧妙的dp)

    BZOJ 1079: [SCOI2008]着色方案(巧妙的dp) 题意:有\(n\)个木块排成一行,从左到右依次编号为\(1\)~\(n\).你有\(k\)种颜色的油漆,其中第\(i\)种颜色的油漆足 ...

  6. [BZOJ 1079][SCOI 2008]着色方案

    1079: [SCOI2008]着色方案 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2237  Solved: 1361[Submit][Stat ...

  7. bzoj 1079: [SCOI2008]着色方案 DP

    1079: [SCOI2008]着色方案 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 803  Solved: 512[Submit][Status ...

  8. 【BZOJ】1079: [SCOI2008]着色方案(dp+特殊的技巧)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1079 只能想到5^15的做法...........................果然我太弱. 其实 ...

  9. 【BZOJ 1079】[SCOI2008]着色方案

    Description 有n个木块排成一行,从左到右依次编号为1~n.你有k种颜色的油漆,其中第i种颜色的油漆足够涂ci个木块.所有油漆刚好足够涂满所有木块,即c1+c2+...+ck=n.相邻两个木 ...

随机推荐

  1. Simple BeamSearch Codes for Python

    Code from: https://github.com/SeitaroShinagawa/simple_beamsearch probs = [[[],[0.3,0.7]], [[0],[0.1, ...

  2. Python爬虫: "追新番"网站资源链接爬取

    “追新番”网站 追新番网站提供最新的日剧和日影下载地址,更新比较快. 个人比较喜欢看日剧,因此想着通过爬取该网站,做一个资源地图 可以查看网站到底有哪些日剧,并且随时可以下载. 资源地图 爬取的资源地 ...

  3. 16.Oct Working Note

    01 writing algorithm by assembly,but the bug... now,it runs normaly,but how to print the answer? suc ...

  4. Unicode 7.0.1中文支持非常好

    简单测试了一下,7.0.1中文支持非常好.Delphi7下将UniConnection的useUnicode设置为False,Tokyo下设置为True,Charset空着即可. 问题要点:1.建数据 ...

  5. 深入解析Windows窗口创建和消息分发(三个核心问题:怎么将不同的窗口过程勾到一起,将不同的hwnd消息分发给对应的CWnd类去处理,CWnd如何简单有效的去处理消息,由浅入深,非常清楚) good

    笔记:争取不用看下面的内容,只看自己的笔记,就能记住这个流程,就算明白了: _tWinMain-->AfxWinMain,它调用四个函数: -->AfxWinInit用于做一些框架的初始化 ...

  6. getch(),getche(),getchar()的区别

    先说基本区别. (1) getch()和getche()函数     这两个函数都是从键盘上读入一个字符.其调用格式为:      getch();      getche();     两者的区别是 ...

  7. hdu4616_Game_树形DP

    以为很水的一道题,花了大半天的时间才搞定,比赛的时候卡在这题上了,伤不起啊... 题意:给一棵树,每个结点中有礼物,每个礼物有一个权值,某些结点中会有陷阱,你可以从任何一点出发,每个结点最多只能经过一 ...

  8. 爬取虎扑NBA首页主干道推荐贴的一只小爬虫,日常爬不冷笑话解闷

    虎扑是广大jrs的家园,步行街是这个家园里最繁华的地段.据称广大jrs平均学历985,步行街街薪30w起步. 大学时经舍友安利,开始了解虎扑,主要是看看NBA的一些资讯. 偶尔也上上这个破街,看看jr ...

  9. 生产环境MySQL优化

    a:硬件的优化: 1. 采用64位cpu,cpu至少4颗,L2缓存越大越好2. 内存要大,32-64G运行1-2个实例,96-128G运行3-4个实例3. 机械盘选用sas盘,转速15000以上,有可 ...

  10. Laravel --- 自动生成数据

    1.创建填充文件:php artisan make:seeder UserTableSeeder 2.在run方法里面写填充数据的代码: use Illuminate\Database\Seeder; ...