Time Limit: 10 Sec Memory Limit: 162 MB

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

  

  

  

Solution

  

  ​ 是不是还想状压啊,行不通的,状态数太多了。

  

​   看看还有什么是比较小的:\(c_i\)看起来很小。

  

​   仔细想一想会发现,如果两种颜料的可使用次数相同,那么它们可以归为一类颜料。

  

  ​ 从可使用次数分类入手,设状态\(f[a_1][a_2][a_3][a_4][a_5][x]\),表示当前已使用\(i\)次的颜料有\(a_i\)种,且下一步将要选择当前可使用\(x\)次的颜料,的总方案数。

  

  ​ 干脆就自顶向下使用记忆化搜索DP实现。每个状态从哪里转移就很显然了:可以挑5类颜料中的一种,那么转移的来源就是\(\{a_1-1,a_2,a_3,a_4,a_5\}\),\(\{a_1+1,a_2-1,a_3,a_4,a_5\}\),\(\{a_1,a_2+1,a_3-1,a_4,a_5\}\),\(\{a_1,a_2,a_3+1,a_4-1,a_5\}\),\(\{a_1,a_2,a_3,a_4+1,a_5-1\}\)。

  

​   关键是转移的系数和递归参数。简单的讲,每类颜料\(i\)有\(a_i\)种不同的选法,但这没有考虑到题目要求两两不同给的限制。

  

​   注意每个状态的\(a_i\)是相对于当前状态下的信息,而\(x\)则是上一层状态给你做出的限制。你枚举当前这一步将要挑哪一类颜料,递归的时候就要把这类颜料作为下一步的\(x\)传进去,表示你下一层自己选择的时候,如果要选我这一层选择的这类颜料,你可用的选择数必须减1,否则将会和我冲突。而上一层递归给这一层传进了\(x\),说明上一层递归所挑的颜料在上一层为第\(x\)类,那么在这一层则是第\(x-1\)类(没用之前即减1)。如果你枚举当前层选择了第\(x-1\)类颜料,可用方案数必须减1。

  

​   需要梳理一下思路和控制关系,实现起来并不难。

  

  

  

#include <cstdio>
#include <cstring>
using namespace std;
const int N=16,MOD=1e9+7;
int n,a[6],c[6];
int f[N][N][N][N][N][6];
int dfs(int a1,int a2,int a3,int a4,int a5,int x){
int &F=f[a1][a2][a3][a4][a5][x];
if(F!=-1) return F;
F=0;
if(a1)
(F+=1LL*dfs(a1-1,a2,a3,a4,a5,1)*(a1-(x-1==1))%MOD)%=MOD;
if(a2)
(F+=1LL*dfs(a1+1,a2-1,a3,a4,a5,2)*(a2-(x-1==2))%MOD)%=MOD;
if(a3)
(F+=1LL*dfs(a1,a2+1,a3-1,a4,a5,3)*(a3-(x-1==3))%MOD)%=MOD;
if(a4)
(F+=1LL*dfs(a1,a2,a3+1,a4-1,a5,4)*(a4-(x-1==4))%MOD)%=MOD;
if(a5)
(F+=1LL*dfs(a1,a2,a3,a4+1,a5-1,5)*a5%MOD)%=MOD;
return F;
}
int main(){
freopen("input.in","r",stdin);
scanf("%d",&n);
for(int i=1;i<=n;i++){
int x;
scanf("%d",&x);
c[x]++;
}
memset(f,-1,sizeof f);
for(int i=0;i<=5;i++)
f[0][0][0][0][0][i]=1;
printf("%d\n",dfs(c[1],c[2],c[3],c[4],c[5],0));
return 0;
}

【BZOJ1079】【SCOI2008】着色方案的更多相关文章

  1. BZOJ1079 [SCOI2008]着色方案 动态规划

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1079 题目概括 有n个木块排成一行,从左到右依次编号为1~n.你有k种颜色的油漆,其中第i种颜色的 ...

  2. [luogu2476][bzoj1079][SCOI2008]着色方案【动态规划】

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

  3. BZOJ1079:[SCOI2008]着色方案(DP)

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

  4. BZOJ1079 [SCOI2008]着色方案 【dp记忆化搜索】

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

  5. BZOJ1079: [SCOI2008]着色方案 (记忆化搜索)

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

  6. 2018.10.20 bzoj1079: [SCOI2008]着色方案(多维dp)

    传送门 dp妙题. f[a][b][c][d][e][last]f[a][b][c][d][e][last]f[a][b][c][d][e][last]表示还剩下aaa个可以用一次的,还剩下bbb个可 ...

  7. BZOJ1079 [SCOI2008]着色方案[组合计数DP]

    $有a_{1}个1,a_{2}个2,...,a_{n}个n(n<=15,a_{n}<=5),求排成一列相邻位不相同的方案数.$ 关于这题的教训记录: 学会对于复杂的影响分开计,善于发现整体 ...

  8. bzoj1079: [SCOI2008]着色方案

    dp.以上次染色时用的颜色的数量和每种数量所含有的颜色作状态. #include<cstdio> #include<algorithm> #include<cstring ...

  9. 【记忆化搜索】bzoj1079 [SCOI2008]着色方案

    #include<cstring> #include<cstdio> using namespace std; #define MOD 1000000007 typedef l ...

  10. bzoj1079: [SCOI2008]着色方案

    ci<=5直接想到的就是5维dp了...dp方程YY起来很好玩...写成记忆化搜索比较容易 #include<cstdio> #include<cstring> #inc ...

随机推荐

  1. 【Skynet】Traceback汇总

    error: ./skynet/lualib/skynet.lua:534: ./skynet/lualib/skynet.lua:156: ./logic/gate/socket_msg.lua:5 ...

  2. .NET处理Json的几种方式

    序列化里的xml,soap,binary在上一篇文章里面已经说过了,这篇主要说json. json是目前非常流行的一种序列化数据的方式,很多api都采用的是json,结构简洁,容易理解,适用性强,逐渐 ...

  3. Redis勒索事件爆发,如何避免从删库到跑路?

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由腾讯云数据库 TencentDB发表于云+社区专栏 9月10日下午,又一起规模化利用Redis未授权访问漏洞攻击数据库的事件发生,此次 ...

  4. 打包应用和构建Docker镜像(docker在windows上)

    在构建Docker时编译应用 一般有两种方法在构建镜像时进行打包应用.第一种方法就是使用基本的镜像,该镜像包括应用平台和构建工具,因此在Dockerfile中,复制源代码到镜像中并在构建镜像时编译ap ...

  5. tensorflow enqueue_many传入多个值的列表传入异常问题————Shape () must have rank at least 1

    tf 的队列操作enqueue_many传入的值是列表,但是放入[]列表抛异常 File "C:\Users\lihongjie\AppData\Local\Programs\Python\ ...

  6. to_char

    to_date(to_char(to_date(#{conds.currentTime,jdbcType=VARCHAR},'YYYY-MM-DD hh24:mi:ss'),'hh24:mi:ss') ...

  7. Scrum Meeting 3 -2014.11.5

    这几天小伙伴们都在努力,研究出不少改进方案并加以设计和实施了,分词算法的优化进度可观,而其他的任务在改进的过程中产生了些问题,对于之前代码的设计感到疑惑,我们找到了上届的学长们咨询,他们也给出了不少建 ...

  8. Linux 读书笔记 三 (第二章)

      一.学习目标 1. 理解二进制在计算机中的重要地位 2. 掌握布尔运算在C语言中的应用 3. 理解有符号整数.无符号整数.浮点数的表示 4. 理解补码的重要性 5. 能避免C语言中溢出,数据类型转 ...

  9. c# 程序重启设定

    问题情境: 程序随着时间运行,越来越大.暂时想到的两种方法,一是反攻代码,查看占内存大的函数,是不是没有回收.再就是暴力设定程序定时重启. 解决原理: 定时重启:暂设定timer,时间匹配执行rest ...

  10. diliucizuoye

    NABCD N(Need 需求) 互联网的高速发展,造就了二十一世纪这个追求高品质.高体验的信息时代,随其发展改变的是信息记录与分享方式,从传统的面对面交流.手机通话.写日记本,到现如今的社交平台.信 ...