description

给定一个由前n个小写字母组成的串S。

串S是阶乘字符串当且仅当前n个小写字母的全排列(共n!种)都作为S的子序列(可以不连续)出现。

由这个定义出发,可以得到一个简单的枚举法去验证,但是它实在太慢了。所以现在请你设计一个算法,在1秒内判断出给定的串是否是阶乘字符串。


analysis

  • 状压\(DP\)

  • 不知道为什么\(22\)个字母或以上的都不合法

  • 设\(f[S]\)表示\(S\)状态中为\(1\)的字母的全排列全都出现过的最前位置

  • 转移就是在某个全排列的末尾插上一个新字母,枚举新字母转移

  • 先预处理出每个位置到某下一字母的最前位置,就可以容易地\(DP\)了


code

#include<stdio.h>
#include<string.h>
#include<algorithm>
#define MAXN 2100000
#define INF 1000000007
#define ll long long
#define fo(i,a,b) for (ll i=a;i<=b;++i)
#define fd(i,a,b) for (ll i=a;i>=b;--i) using namespace std; ll f[MAXN];
ll g[500][26];
char st[500];
ll n,T,len; inline ll read()
{
ll x=0,f=1;char ch=getchar();
while (ch<'0' || '9'<ch){if (ch=='-')f=-1;ch=getchar();}
while ('0'<=ch && ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
inline ll max(ll x,ll y){return x>y?x:y;}
int main()
{
freopen("T2.in","r",stdin);
T=read();
while (T--)
{
n=read(),scanf("\n%s",st+1);
if (n>21){printf("NO\n");continue;}
len=strlen(st+1);
fo(i,0,n-1)g[len][i]=g[len+1][i]=len+1;
fd(i,len-1,0)
{
fo(j,0,n-1)g[i][j]=g[i+1][j];
g[i][st[i+1]-'a']=i+1;
}
memset(f,0,sizeof(f));
fo(status,1,(1<<n)-1)
{
fo(i,0,n-1)if (status&(1<<i))
f[status]=max(f[status],g[f[status^(1<<i)]][i]);
}
printf(f[(1<<n)-1]==len+1?"NO\n":"YES\n");
}
return 0;
}

【JZOJ3293】【BZOJ4416】【luoguP3989】阶乘字符串的更多相关文章

  1. BZOJ4416 [Shoi2013]阶乘字符串 【序列自动机 + 状压dp】

    题目链接 BZOJ4416 题解 建立序列自动机,即预处理数组\(nxt[i][j]\)表示\(i\)位置之后下一个\(j\)出现的位置 设\(f[i]\)表示合法字符集合为\(i\)的最短前缀,枚举 ...

  2. [BZOJ4416][SHOI2013]阶乘字符串(子集DP)

    怎么也没想到是子集DP,想到了应该就没什么难度了. 首先n>21时必定为NO. g[i][j]表示位置i后的第一个字母j在哪个位置,n*21求出. f[S]表示S的所有全排列子序列出现的最后末尾 ...

  3. BZOJ4416 SHOI2013阶乘字符串(状压dp)

    当n大到一定程度(>21)时一定无解,并不会证. 如果要取出一个排列,显然应该让每一位在序列中的位置尽量靠前.于是设f[S]表示存在S子集中这些字母所组成的所有排列的最短前缀的长度,枚举当前排列 ...

  4. BZOJ4416: [Shoi2013]阶乘字符串

    可以大胆猜想n>21时无解,至于依据,不开O2,1s,n<=21刚好能卡过去= = 并不会证= = #include<cstdio> void up(int& a,in ...

  5. [JZOJ3293] 【SHTSC2013】阶乘字符串

    题目 题目大意 给你一个字符串,判断这个字符串是否为"阶乘字符串". 就是子序列包含字符集的全排列的字符串. n≤26n\leq 26n≤26 ∣S∣≤450|S|\leq 450 ...

  6. 洛谷 P3989 [SHOI2013]阶乘字符串 解题报告

    P3989 [SHOI2013]阶乘字符串 题目描述 给定一个由前\(n(\le 26)\)个小写字母组成的串\(S(|S|\le 450)\).串\(S\)是阶乘字符串当且仅当前 \(n\) 个小写 ...

  7. BZOJ 4416 【SHOI2013】 阶乘字符串

    题目链接:阶乘字符串 又是一道不会做的题……看了题解后我被吓傻了…… 首先我们可以有一个显然的\(O(2^nn)\)的做法.我们先预处理出\(g_{i,j}\)表示字符串中\(i\)号位置开始第一个\ ...

  8. [SHOI2013]阶乘字符串

    题目描述 给定一个由前\(n\)个小写字母组成的串\(S\). 串\(S\)是阶乘字符串当且仅当前\(n\)个小写字母的全排列(共\(n!\)种)都作为\(S\)的子序列(可以不连续)出现. 由这个定 ...

  9. [暑假的bzoj刷水记录]

    (这篇我就不信有网站来扣) 这个暑假打算刷刷题啥的 但是写博客好累啊  堆一起算了 隔一段更新一下.  7月27号之前刷的的就不写了 , 写的累 代码不贴了,可以找我要啊.. 2017.8.27upd ...

随机推荐

  1. layui的layer独立版报错“TypeError: i is not a function”的解决

    折腾良久发现是引入jQuery顺序的问题. jQuery必须在layer引入之前引入.

  2. 小米手机 - Charles无法安装证书 因为无法读取证书

    1.不要使用小米原装的浏览器安装证书 2.使用第三方浏览器安装,如我使用的是UC浏览器 3.使用第三方浏览器安装的证书格式是".pem"格式问卷 4.将这个文件放入小米的downl ...

  3. 笔记65 Spring Boot快速入门(五)

    SpringBoot+JPA 一.什么是JPA? JPA是Java Persistence API的简称,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期 ...

  4. MATLAB GUI 设计要点 转

    https://www.cnblogs.com/wangh0802PositiveANDupward/p/4588512.html 从简单的例子说起吧. 创建Matlab GUI界面通常有两种方式: ...

  5. informix 计算 日期之差

    原文地址:http://blog.chinaunix.net/uid-678894-id-3138829.html https://blog.csdn.net/zhengqiqiqinqin/arti ...

  6. 在CMake中启用VS2017的C++17特性

    VS2017的C++17特性默认并未开启,需要在编译参数中手动开启.找到项目的CMakeLists.txt,在查找编译器的代码后面加入如下内容即可. ") include(CheckCXXC ...

  7. git——commit成功后,GitHub方格不变绿

    一通百度该设置的都设置了,还是不好使 发现有提示一栏 pull request的东西  在网上查貌似是因为两个分支内容不同 提示是否合并,还查到了不变绿可能的原因. Contributions未被Gi ...

  8. 云原生数据库崛起,阿里云POLARDB当选世界互联网领先科技成果!

    第六届世界互联网大会来了!千年水乡古镇乌镇又一次吸引了全世界的目光. 刚刚,阿里云自研数据库POLARDB在会上当选世界互联网领先科技成果.POLARDB解决了企业在云时代的数据库难题,帮助企业在数小 ...

  9. 剑指offer---2、二叉搜索树的后序遍历序列

    剑指offer---2.二叉搜索树的后序遍历序列 一.总结 一句话总结: 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字 ...

  10. (转) C#中使用throw和throw ex抛出异常的区别

    通常,我们使用try/catch/finally语句块来捕获异常,就像在这里说的.在抛出异常的时候,使用throw和throw ex有什么区别呢? 假设,按如下的方式调用几个方法: →在Main方法中 ...