题目大意

有 \(n\) 个白色的小球排成一排,有一个长为 \(k\) 的字符串 \(S\)。接下来进行 \(k\) 次操作。

第 \(i\) 个操作,选择一段连续的小球(可以为空),若 \(S\) 中第 \(i\) 个字符是 r,则将这些球染成红色;若是 b,则将它们染成蓝色。由于染料的特性,不能直接用蓝色来染白色。

求在进行完所有操作后,所有小球的颜色序列可以有多少种。

对 \(10^9+7\) 取模。

\(n,k\le 70\).

解题思路

首先,因为考虑按顺序进行染色操作的结果非常复杂,而且难以分辨重复状态,所以不妨考虑如何判断一个序列是否合法。

不妨假设整个序列有 \(m\) 个有色段,每段的蓝色段个数为 \(b_i\)。

显然对于 \(b_i=0\) 的段,只需要一个 r;而对于 \(b_i>1\) 的段,经过手玩不难发现,它需要一个 rb,以及 \(b_i-1\) 次任意染色。

所以假设我们已经有了 \(b\) 数组,不妨贪心地达成染色方案:

按照 \(b_i\) 的从大到小排序,首先尽量选最靠前的 r,然后对于 \(b_i>0\) 的,在选的 r 之后尽量选最靠前的 b,最后对于 \(b_i>1\) 的,选择 rb 后最靠前的 \(b_i-1\) 个操作。

因为 \(n\le 70\),可以用复杂度划分数相关的做法,那么不妨直接类似划分数枚举 \(b_i\) 的情况。

接下来对于已经确定的一组 \(b_i\) 如何求方案的思路,个人感觉比较妙 (从 xht37 那里学到的)。

以 \(b={1,2,2,3,4}\) 为例,首先是一个多重组合数 \(\binom{5}{1,2,1,1}\),然后是具体染色的方案数。

这个序列对应的染色序列一定包含子序列 R W B W B W BRB W BRBRB,也就是每个 \(b_i\) 的最短可能,长度为 \(15\)。

同时,其对应的染色序列一定是 W R W RBR W RBR W RBRBR W RBRBRBR W 的子序列,也就是每个 \(b_i\) 的最长可能,长度为 \(25\)。

而此时我们的染色序列是把相邻的同色球缩到一起,所以最终方案相当于把 \(n-15\) 个字符分成 \(25\) 组,每组可以为空的方案数。答案为 \(\binom{n-15+25-1}{25-1}\)。

#include <bits/stdc++.h>
#define lfor(x, y, z) for(int x(y), x##_end(z); x <= x##_end; ++x)
#define rfor(x, y, z) for(int x(y), x##_end(z); x >= x##_end; --x)
#define lep(x, y, z) for(int x(y), x##_end(z); x < x##_end; ++x)
#define ls(x) t[x].lc
#define rs(x) t[x].rc
#define LL long long
using namespace std; const int N(205), mod(1e9 + 7); int n, K; char ch[N];
int Ans;
int m, b[N];
int ban[N], loc[N];
int fac[N], ifac[N];
int div_cnt; template <typename T> inline void read(T &x){
x = 0; int f = 1, c = getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
while(isdigit(c)) x = x * 10 + c - '0', c = getchar();
x *= f;
} inline int Mod(int x){ return x + ((x >> 31) & mod); }
inline void MOD(int &x){ x = x + ((x >> 31) & mod); }
inline int C(int n, int m){
if(n < m || m < 0) return 0;
return (LL) fac[n] * ifac[n - m] % mod * ifac[m] % mod;
}
inline int qpow(int x, int a = mod - 2){
int sum = 1;
while(a) sum = a & 1 ? (LL) sum * x % mod : sum, x = (LL) x * x % mod, a >>= 1;
return sum;
} void prep(int n = 200){
fac[0] = 1; lfor(i, 1, n) fac[i] = (LL) fac[i - 1] * i % mod;
ifac[n] = qpow(fac[n]); rfor(i, n - 1, 0) ifac[i] = (LL) ifac[i + 1] * (i + 1) % mod;
} bool legal(){
int now = 1, sum = m - 1; lfor(i, 1, K) ban[i] = 0;
lfor(i, 1, m) if(b[i]) sum += b[i] * 2 - 1; if(sum > n) return 0; rfor(i, m, 1){
while(now <= K && ch[now] != 'r') ++now;
if(now > K || ch[now] != 'r') return 0; loc[i] = now, ban[now] = 1, ++now;
} now = 1;
rfor(i, m, 1) if(b[i]){
now = max(now, loc[i] + 1);
while(now <= K && ch[now] != 'b') ++now;
if(now > K || ch[now] != 'b') return 0; loc[i] = now, ban[now] = 1, ++now;
} now = 1;
rfor(i, m, 1) if(b[i]){
int sum = b[i] - 1;
now = max(now, loc[i] + 1);
while(now <= K && sum) sum -= !ban[now], ++now;
if(sum) return 0;
}
return 1;
} inline int Calc(){
int sum = fac[m], p = 1;
lfor(i, 2, m) if(b[i] != b[p]) sum = (LL) sum * ifac[i - p] % mod, p = i;
return (LL) sum * ifac[m - p + 1] % mod;
}
void check(){
if(!legal()) return;
int A = m - 1, B = m + 1;
lfor(i, 1, m){
if(b[i] == 0) A += 1, B += 1;
else A += b[i] * 2 - 1, B += b[i] * 2 + 1;
}
int tmp = (LL) Calc() * C(n - A + B - 1, B - 1) % mod;
MOD(Ans += (LL) Calc() * C(n - A + B - 1, B - 1) % mod - mod);
}
void dfs(int R, int A, int L, int lst){
check();
++m;
for(int i = lst; R && i + 1 <= A && L + max(1, i * 2 - 1) <= n + 1; ++i)
b[m] = i, dfs(R - 1, A - 1 - i, L + max(1, i * 2 - 1), i);
--m;
} int main(){
read(n), read(K), prep();
scanf("%s", ch + 1); int cntr = 0, cntb = 0;
lfor(i, 1, K) if(ch[i] == 'r') ++cntr; else ++cntb; dfs(cntr, K + 1, 0, 0); cout << Ans << endl;
return 0;
}

[题解][ARC089D] ColoringBalls的更多相关文章

  1. 贪心/构造/DP 杂题选做Ⅲ

    颓!颓!颓!(bushi 前传: 贪心/构造/DP 杂题选做 贪心/构造/DP 杂题选做Ⅱ 51. CF758E Broken Tree 讲个笑话,这道题是 11.3 模拟赛的 T2,模拟赛里那道题的 ...

  2. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  3. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  4. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  5. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  6. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  7. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  8. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  9. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

随机推荐

  1. 在 Spring中如何注入一个java集合?

    Spring提供以下几种集合的配置元素: 类型用于注入一列值,允许有相同的值. 类型用于注入一组值,不允许有相同的值. 类型用于注入一组键值对,键和值都可以为任意类型. 类型用于注入一组键值对,键和值 ...

  2. 如何在 spring 中启动注解装配?

    默认情况下,Spring 容器中未打开注解装配.因此,要使用基于注解装配,我们 必须通过配置 <context:annotation-config/> 元素在 Spring 配置文件 中启 ...

  3. memcached 最大的优势是什么?

    Memcached 最大的好处就是它带来了极佳的水平可扩展性,特别是在一个巨大的 系统中.由于客户端自己做了一次哈希,那么我们很容易增加大量 memcached 到集群中.memcached 之间没有 ...

  4. c++ 虚函数多态、纯虚函数、虚函数表指针、虚基类表指针详解

    静态多态.动态多态 静态多态:程序在编译阶段就可以确定调用哪个函数.这种情况叫做静态多态.比如重载,编译器根据传递给函数的参数和函数名决定具体要使用哪一个函数.动态多态:在运行期间才可以确定最终调用的 ...

  5. 如何制作icon-font小图标

    1.首先可以去iconfont.cn阿里巴巴矢量字体库中下载你想要的图标(选择格式为SNG格式). 2.打开iconmoon这个网站(这个样子的),然后点击右上角那个Iconfont App如下图: ...

  6. 为什么局部内部类访问外边的局部变量必须为final

    6.局部内部类访问外边的局部变量时,此变量必须为final类型 马克-to-win:由于技术方面的限制,java的设计者们做出如下语法规定:局部内部类访问外边的局部变量时,此变量必须为final类型, ...

  7. css3属性之filter初探

    filter属性是css不常用的一个属性,但是用好了可以给网页增色不少!ps: IE不支持此属性: img { -webkit-filter: grayscale(100%); /* Chrome, ...

  8. 【零碎小bug系列】windows下的回车和换行符,cmd(telnet)上输出不左对齐

    cmd(telnet)上输出不左对齐,而是有莫名其妙的空格 目录 cmd(telnet)上输出不左对齐,而是有莫名其妙的空格 背景 解决 细究 背景 在cmd上使用telnet连接本地端口的服务器时, ...

  9. Java报错:Injection of resource dependencies failed

    在学习springMVC+Mabatis的时候,添加注解@Resource报错 Injection of resource dependencies failed de完bug后发现有几个点注意一下, ...

  10. Python入门-pip模块管理工具

    安装 # 在线安装 pip install <包名> 安装后,该模块文件会在安装python环境目录:lib/packages目录下 # 安装本地安装包 pip install <目 ...