题目大意

有一个 01 串集合 \(S\),其中每个串的长度都不超过 \(N\),你要求出 \(S\) 中至少是 \(K\) 个串的子序列的最长串,如果有多解,输出字典序最小的那组解。

由于 \(S\) 可能很大,因此我们是这样描述 \(S\) 的:

  • 你将得到 \((N+1)\) 个 01 串,第 \(i\) 个串的长度为 \(2^{i-1}\)。
  • 第 \(i\) 个字符串的第 \(j\) 个字符,代表数字 \((j−1)\) 的、长度为 \((i−1)\) 的二进制表示是否出现在 \(S\) 中。

\(N \leq 20\)。

解题思路

讲题的时候一直讲子序列自动机搞得我以为解法是 YY 一个广义子序列自动机什么的,嘤。

其实是用贪心的思想去匹配,然后记录每种匹配过程的可能性,再压状态。

用 \(f(S_1, S_2)\) 表示已经匹配的子序列是 \(S_1\),还可匹配的串是 \(S_2\) 的情况数。

显然初始是 \(f(\empty,T) = 1\),而每个字符串的答案是 \(f(S,\empty)\)。转移就枚举下一个匹配 \(0/1\) 就好了。

需要注意的是状态要压一压。

考虑记录成 \(f(len,S_1|S_2)\) 即因为 \(|S_1|+|S_2|\le N\),所以把两者存在一起,空间复杂度才对。

只有 \(len\) 是找不到分割点的,不知道 \(0\) 到底是空,还是匹配了一位 \(0\),不过每个串前面补个 \(1\) 就好了。

不仅是题解代码的两倍长,空间复杂度还很高 QAQ

#include <set>
#include <map>
#include <queue>
#include <bitset>
#include <vector>
#include <math.h>
#include <ctype.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
/*
添加 1 应该完全不影响才是()
除了 f 数组的第一维,所有的长度都一定是字符串的实际长度,包括添加的 1 ;
S 和 S1 一定是 1 开头,但是 S2 不一定;
原字符串最长为 n,有 (1 << n + 1) - 1 种
新字符串最长为 n + 1,有 (1 << n + 2) - 1 种
*/
const int N(20); int n, k;
int f[2][1 << N + 1], g[N + 1][1 << N + 1];
int s[1 << N + 1], len[1 << N + 1];
char ch[1 << N];
struct pal{ int l, S; } nx[N + 2][1 << N + 1][2]; inline void read(int &x){
x = 0; int f = 1, c = getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
while(isdigit(c)) x = x * 10 + c - 48, c = getchar();
x *= f;
} inline void out(int len, int S){
if(len < 0) return; if(len == 0){ cerr << "empty\n"; return; }
for(int i(len - 1); ~i; --i) printf("%d", !!(S & (1 << i)));
puts("");
} void input(){
read(n), read(k);
for(int i(0); i <= n; ++i){
scanf("%s", ch); int m = strlen(ch);
for(int j(0); j < m; ++j)
len[j | (1 << i)] = i + 1, s[j | (1 << i)] = ch[j] - '0';
}
} void init(){
for(int i(1); i < 1 << n + 1; ++i) if(s[i]) f[0][i] = 1;
nx[0][0][0] = nx[0][0][1] = {-1};
for(int i(1); i <= n + 1; ++i)
for(int j(0); j < 1 << i; ++j){
int p = j >> (i - 1), S = j & (1 << i - 1) - 1;
nx[i][j][p] = {i - 1, S};
nx[i][j][p ^ 1] = nx[i - 1][S][p ^ 1];
}
} void match(){
for(int i(0); i <= n; ++i){
int p = i & 1; memset(f[!p], 0, sizeof f[p]);
for(int j(1); j < 1 << n + 1; ++j){
int S = j; if(!f[p][S]) continue; pal nw;
int S1, S2, l, l1, l2; l = len[S], l1 = i + 1, l2 = l - l1;
S1 = S >> l2, S2 = S & (1 << l2) - 1;
nw = nx[l2][S2][0];
if(nw.l != -1) f[!p][((S1 << 1) << nw.l) | nw.S] += f[p][S];
nw = nx[l2][S2][1];
if(nw.l != -1) f[!p][((S1 << 1 | 1) << nw.l) | nw.S] += f[p][S];
g[i][S1] += f[p][S];
}
}
} void output(){
for(int i(n); ~i; --i)
for(int j(0); j < 1 << i; ++j)
if(g[i][j | (1 << i)] >= k) return out(i, j);
} int main(){
input();
init();
match();
output();
return 0;
}
/* Hemerocallis */

[题解] [AGC024F] Simple Subsequence Problem的更多相关文章

  1. @atcoder - AGC024F@ Simple Subsequence Problem

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定由若干长度 <= N 的 01 字符串组成的集合 S. ...

  2. hdu4976 A simple greedy problem. (贪心+DP)

    http://acm.hdu.edu.cn/showproblem.php?pid=4976 2014 Multi-University Training Contest 10 1006 A simp ...

  3. HDU1757 A Simple Math Problem 矩阵快速幂

    A Simple Math Problem Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot ...

  4. SPOJ LIS2 Another Longest Increasing Subsequence Problem 三维偏序最长链 CDQ分治

    Another Longest Increasing Subsequence Problem Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://a ...

  5. FZYZ-2071 A Simple Math Problem IX

    P2071 -- A Simple Math Problem IX 时间限制:1000MS      内存限制:262144KB 状态:Accepted      标签:    数学问题-博弈论    ...

  6. HDU 1757 A Simple Math Problem(矩阵)

    A Simple Math Problem [题目链接]A Simple Math Problem [题目类型]矩阵快速幂 &题解: 这是一个模板题,也算是入门了吧. 推荐一个博客:点这里 跟 ...

  7. 【BZOJ3489】A simple rmq problem(KD-Tree)

    [BZOJ3489]A simple rmq problem(KD-Tree) 题面 BZOJ 题解 直接做肯定不好做,首先我们知道我们是一个二维平面数点,但是限制区间只能出现一次很不好办,那么我们给 ...

  8. 【BZOJ3489】A simple rmq problem

    [BZOJ3489]A simple rmq problem 题面 bzoj 题解 这个题不强制在线的话随便做啊... 考虑强制在线时怎么搞 预处理出一个位置上一个出现的相同数的位置\(pre\)与下 ...

  9. BZOJ3489 A simple rmq problem 【可持久化树套树】*

    BZOJ3489 A simple rmq problem Description 因为是OJ上的题,就简单点好了.给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过一 ...

随机推荐

  1. 手撕代码:leetcode70爬楼梯

    装载于:https://blog.csdn.net/qq_35091252/article/details/90576779 题目描述 假设你正在爬楼梯.需要n阶你才能到达楼顶. 每次你可以爬1或2个 ...

  2. ApplicationContext通常的实现是什么?

    FileSystemXmlApplicationContext :此容器从一个XML文件中加载beans的定义,XML Bean 配置文件的全路径名必须提供给它的构造函数. ClassPathXmlA ...

  3. Bootstrap Javascript组件,模态框级联open解决方案

    <script type="text/javascript"> top.global={zIndex:null}; $("body>div[data-m ...

  4. element-ui 无法对绑定表单的对象中的对象属性进行验证

    <el-form-item label="类型" :label-width="formLabelWidth" prop="typeId" ...

  5. func-spring-boot-starter 匿名函数托管

    func-spring-boot-starter 匿名函数托管 GitHub项目路径: https://github.com/yiurhub/func-spring-boot-starter Gite ...

  6. SringBoot之yaml语法

    ------------恢复内容开始------------ SpringBoot之yaml语法 1.配置文件 官方配置文档太多了,根本记不住! 怎么办呐-->了解原理 SpringBoot使用 ...

  7. ML、DL及RL介绍和区别

    前言 在刚入门的时候,我们很容易被这些词语弄得眼花缭乱,如人工智能.机器学习.深度学习及强化学习等等.它们之间互相联系,却有一定区别.我们学习人工智能AI,需要对这些词语有一定的概念,不然,研究了这么 ...

  8. 巧用CSS3:target 伪类制作Dropdown下拉菜单(无JS)

    原文链接:http://devework.com/css3-target-dropdown.html :target 是CSS3 中新增的一个伪类,用以匹配当前页面的URI中某个标志符的目标元素(比如 ...

  9. IMWeb前端提升营七天学习总结

    写在前面 5月24到30这7天,IMWeb前端提升营,腾讯大佬们分享个人经验,使出各种前端方面的大招.从中学习了很多前端方面的知识,也get到了前端学习的方法论,还有一些算法知识等等. 现将总结如下: ...

  10. 如何监控微信小程序HTTP请求错误

    摘要: Fundebug的微信小程序错误监控插件更新至0.5.0,支持监控HTTP请求错误. 接入插件 接入Fundebug的错误监控插件非常简单,只需要下载fundebug.0.5.0.min.js ...