[题解] [AGC024F] Simple Subsequence Problem
题目大意
有一个 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的更多相关文章
- @atcoder - AGC024F@ Simple Subsequence Problem
目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定由若干长度 <= N 的 01 字符串组成的集合 S. ...
- hdu4976 A simple greedy problem. (贪心+DP)
http://acm.hdu.edu.cn/showproblem.php?pid=4976 2014 Multi-University Training Contest 10 1006 A simp ...
- HDU1757 A Simple Math Problem 矩阵快速幂
A Simple Math Problem Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
- SPOJ LIS2 Another Longest Increasing Subsequence Problem 三维偏序最长链 CDQ分治
Another Longest Increasing Subsequence Problem Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://a ...
- FZYZ-2071 A Simple Math Problem IX
P2071 -- A Simple Math Problem IX 时间限制:1000MS 内存限制:262144KB 状态:Accepted 标签: 数学问题-博弈论 ...
- HDU 1757 A Simple Math Problem(矩阵)
A Simple Math Problem [题目链接]A Simple Math Problem [题目类型]矩阵快速幂 &题解: 这是一个模板题,也算是入门了吧. 推荐一个博客:点这里 跟 ...
- 【BZOJ3489】A simple rmq problem(KD-Tree)
[BZOJ3489]A simple rmq problem(KD-Tree) 题面 BZOJ 题解 直接做肯定不好做,首先我们知道我们是一个二维平面数点,但是限制区间只能出现一次很不好办,那么我们给 ...
- 【BZOJ3489】A simple rmq problem
[BZOJ3489]A simple rmq problem 题面 bzoj 题解 这个题不强制在线的话随便做啊... 考虑强制在线时怎么搞 预处理出一个位置上一个出现的相同数的位置\(pre\)与下 ...
- BZOJ3489 A simple rmq problem 【可持久化树套树】*
BZOJ3489 A simple rmq problem Description 因为是OJ上的题,就简单点好了.给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过一 ...
随机推荐
- 集成SpringCloudBus,但没有总线通知更改
配置服务端别忘了添加以下2个依赖 implementation("org.springframework.cloud:spring-cloud-config-server")imp ...
- spring-boot-learning-Web开发知识
1).创建SpringBoot应用,选中我们需要的模块: 2).SpringBoot已经默认将这些场景配置好了,只需要在配置文件中指定少量配置就可以运行起来 3).自己编写业务代码: 文件名的功能 x ...
- 使用kindeditor
首先在http://kindeditor.net/demo.php下载样式 点击右上角的下载按钮 点击官方下载下载之后解压出来 然后在桌面创建一个文件夹 然后回到刚才的http://kindedito ...
- 初识mybatis(为什么是mybatis?)
对原生态的 jdbc 中的问题总结 1.数据库连接,使用就创建,不使用立即释放,对数据库进行频繁连接开启和关闭,造成数据库资源浪费,影响数据库性能. 设想:使用数据库连接池管理数据库连接 2.将sql ...
- FR9833 32V转5V
- Emscripten教程之代码可移植性与限制(一)
Emscripten教程之代码可移植性与限制(一) 翻译:云荒杯倾本文是Emscripten-WebAssembly专栏系列文章之一,更多文章请查看专栏.也可以去作者的博客阅读文章.欢迎加入Wasm和 ...
- WePY为了兼容支付宝小程序,改了好几十行代码
早在16年底,就有流出支付宝在做小程序的事情,见<如何看待支付宝推出「小程序」?>,今年8月18号支付宝版本小程序的终于公测,十月怀胎实属不易啊. 紧接着就有人给我提ISSUE了: 此时我 ...
- React系列——websocket群聊系统在react的实现
前奏 这篇文章仅对不熟悉在react中使用socket.io的人.以及websocket入门者有帮助. 下面这个动态图展示的聊天系统是用react+express+websocket搭建的,很模糊吧, ...
- 从kill-chain的角度检测APT攻击
前言 最近一直在考虑如何结合kill chain检测APT攻击.出发点是因为尽管APT是一种特殊.高级攻击手段,但是它还是会具有攻击的common feature,只要可以把握住共同特征,就能进行检测 ...
- indexOf返回值问题
String s = "aoood";System.out.println(s.indexOf(""));//返回0 System.out.println(s. ...