相邻色块不同的着色方案,似乎这道题已经见过3个版本了。

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

  1 <= k <= 15,,1 <= ci <= 5。

Solution

  k和ci都这么小,状压肯定没跑了。

  如果你把k和ci的数据范围换一换,你应该会很容易地设计出状态吧。

  我们先试着从5^15的状态表示法入手,看看有什么可改进的地方。

  你会发现有很多状态本质上是一样的,颜色之间其实是没有区别的。

  例如七种颜色的数量{1,4,3,2,2,1,2}和{1,2,3,2,4,2,1}排序后都是{1,1,2,2,2,3,4}。

  所以我们就试着把状态压一压,状态表示为当前每种数量的颜色有多少种。

  这样就状态又变成15^5啦,科学得不要不要的。

  具体状态为f[i][j][k]表示已经涂了i格,状态为j,最后一格涂的是在当前状态中数量为k的颜色,转移自己看着办吧。

  时间复杂度O(n*k^ci*ci^2),记忆化搜索似乎会省掉那个n?(n=Σci)

#include <cstdio>
#include <cstring>
#include <algorithm>
#define MN 1100005
#define mod 1000000007
using namespace std;
int m,n,S;
int g[],ys[],f[][MN][],q[][MN],tp[];
bool u[MN]; inline int read()
{
int n=,f=; char c=getchar();
while (c<'' || c>'') {if(c=='-')f=-; c=getchar();}
while (c>='' && c<='') {n=n*+c-''; c=getchar();}
return n*f;
} inline void rw(int &x,int y) {x+=y; if (x>=mod) x-=mod;} int main()
{
register int x,i,j,k,l,lg,rg,gs;
for (m=read();m--;) ++g[x=read()],n+=x;
for (ys[]=,i=;i<=;++i) ys[i]=ys[i-]<<;
for (i=;i<=;++i) S+=g[i]*ys[i];
for (f[][q[][tp[]=]=S][]=,lg=,rg=,i=;i<n;++i,swap(lg,rg))
{
tp[rg]=;
for (j=;j<=tp[lg];++j) if (!u[q[lg][j]])
for (u[q[lg][j]]=true,k=;k<;f[lg][q[lg][j]][k++]=) if (f[lg][q[lg][j]][k])
for (x=q[lg][j],l=;l;x%=ys[l--]) if (gs=x/ys[l])
if (k!=l)
rw(f[rg][q[lg][j]-ys[l]+ys[l-]][l-],1LL*f[lg][q[lg][j]][k]*gs%mod),
q[rg][++tp[rg]]=q[lg][j]-ys[l]+ys[l-];
else if (gs>)
rw(f[rg][q[lg][j]-ys[l]+ys[l-]][l-],1LL*f[lg][q[lg][j]][k]*(gs-)%mod),
q[rg][++tp[rg]]=q[lg][j]-ys[l]+ys[l-];
for (j=;j<=tp[lg];++j) u[q[lg][j]]=false;
}
printf("%d",f[lg][][]);
}

Last Word

  世界上还有比恶意散播题解的更毒的人吗?

[BZOJ]1079 着色方案(SCOI2008)的更多相关文章

  1. Bzoj 1079 着色方案 题解

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

  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

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

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

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

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

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

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

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

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

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

随机推荐

  1. mysql命令行大全

      1.连接Mysql 格式: mysql -h主机地址 -u用户名 -p用户密码1.连接到本机上的MYSQL.首先打开DOS窗口,然后进入目录mysql\bin,再键入命令mysql -u root ...

  2. 静态链表的C实现(基于数据结构 严蔚敏)

    静态链表是利用一维数组实现逻辑上的单链表结构,结点的逻辑上相邻但物理位置上不一定相邻,因为内存分配上是一次性的,故称为静态. 特点: 预先需要一片连续的存储空间: 非随机存取: 无现成的"内 ...

  3. AngularJS1.X学习笔记9-自定义指令(中)

    今天好大的雨啊!上一节中,我们的指令中的工厂函数中都是返回了一个叫做链接函数的工人函数,事实上我们的工厂函数也是可以返回一个对象,这个对象里面可以包含很多的属性,这使得我们可以创建更加强大的指令. 一 ...

  4. vue表单详解——小白速会

    一.基本用法 你可以用 v-model 指令在表单 <input> 及 <textarea> 元素上创建双向数据绑定. 但 v-model 本质上不过是语法糖.它负责监听用户的 ...

  5. Spring Security入门(2-3)Spring Security 的运行原理 4 - 自定义登录方法和页面

    参考链接,多谢作者: http://blog.csdn.net/lee353086/article/details/52586916 http元素下的form-login元素是用来定义表单登录信息的. ...

  6. C#微信公众号开发——access_token的获取

    access_token是公众号的全局唯一票据,公众号调用各接口时都需使用access_token.正常情况下access_token有效期为7200秒,重复获取将导致上次获取的access_toke ...

  7. 19届华为实习生笔试之判断iPv6地址类型

    题二: 答案: #coding=utf-8 import re,sys str = sys.stdin.readline().strip() def regex(str): result = &quo ...

  8. Object.defineProperties()和Object.defineProperty()方法

    Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象. 语法:Object.defineProperty(obj, pro ...

  9. [洛谷P1198/BZOJ1012][JSOI2008] 最大数 - 树状数组/线段树?

    其实已经学了树状数组和线段树,然而懒得做题,所以至今没写多少博客 Description 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作. 语法:Q L 功能:查询当前数列中末尾L个数 ...

  10. Web 项目报错No suitable driver found for jdbc:mysql://localhost:3306/book 的一个解决办法

    确认jar包加入到了build path中,然后注意版本是否与数据库相配,还要留意将jar包放入WEB-INF下的lib文件夹中