题目大意

有 \(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. SpringBoot DevTools 的用途是什么?

    SpringBoot 开发者工具,或者说 DevTools,是一系列可以让开发过程变得简便的工具.为了引入这些工具,我们只需要在 POM.xml 中添加如下依赖: 1 <dependency&g ...

  2. springboot-数据库访问之jpa

    什么是springDate? springData的作用: 整体简化的架构: JPA :Java Persistence API 如果没有springData 我们需要去学每一种对应的jpa实现, 有 ...

  3. 处理器映射器(HandlerMapping)及处理器适配器(HandlerAdapter)详解(二)

    注解的 处理器映射器 和 处理器适配器 介绍 注解的映射器: 在 Spring3.1 之前使用 DefaultAnnotationHandlerMapping 注解映射器(根据 DispatcherS ...

  4. Citus 分布式 PostgreSQL 集群 - SQL Reference(查询处理)

    一个 Citus 集群由一个 coordinator 实例和多个 worker 实例组成. 数据在 worker 上进行分片和复制,而 coordinator 存储有关这些分片的元数据.向集群发出的所 ...

  5. BMZCTF 2020祥云杯到点了

    2020祥云杯到点了 下载附件得到三个word文档,我们打开第一个文档然后将隐藏文字显示出来 得到提示 我们查看属性应该就是日期了我们先把他记录下来 然后打开第二个文档 输入刚刚的密码 在第二个wor ...

  6. 12 Factor App

    The Twelve-Factor App Introduction In the modern era, software is commonly delivered as a service: c ...

  7. IdentityServer4系列 | 支持数据持久化

    一.前言 在前面的篇章介绍中,一些基础配置如API资源.客户端资源等数据以及使用过程中发放的令牌等操作数据,我们都是通过将操作数据和配置数据存储在内存中进行实现的,而在实际开发生产中,我们需要考虑如何 ...

  8. React 可视化开发工具 Shadow Widget 非正经入门(之五:指令式界面设计)

    本系列博文从 Shadow Widget 作者的视角,解释该框架的设计要点.本篇解释 Shadow Widget 中类 Vue 的控制指令,与指令式界面设计相关. 1. 指令式界面设计 Vue 与 A ...

  9. ASP.NET WebAPI解决跨域问题

    跨域是个很蛋疼的问题...随笔记录一下... 一.安装nuget包:Microsoft.AspNet.WebApi.Core 二.在Application_Start方法中启用跨域 1 protect ...

  10. mysql获取表的列名

    DESC test4 SHOW COLUMNS FROM test4 SELECT COLUMN_NAME  FROM information_schema.columns WHERE table_n ...