题意

链接:https://vjudge.net/problem/HDU-6586

给你一个字符串和k,还有每个字符出现次数的限制,求一个长度为k的字典序最小的满足限制的子序列。

思路

先构造出序列自动机,顺带把num(i,j)(下标为i后面的字符为j的个数)求出来。

题目要求字典序最小,我们就贪心的对每一位每次从a~z枚举,check是否满足。

check(x,y,t):第x位放字符y且第x-1位是原串的下标t所表示的字符。要满足以下几点:

  1. 用过的字符y的数量+1<=r[y]
  2. t后面要有j字符
  3. 每一个字符需要的位置个数和(即∑l[i]-vis[i])<=k-x
  4. 每一个字符当前用过的数量+y字符后面的每一个字符还剩的数量>=每个字符的下限

代码

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
char str[N];
char s[N];
int nxt[N][30],l[N],r[N],num[N][30];
int vis[N],k;
char ans[N];
void getnext()
{
memset(nxt, 0, sizeof(nxt));//初始化为0代表i位置之后没有该字符
memset(num,0,sizeof(num));
memset(vis,0,sizeof(vis));
int len = strlen(str + 1);//长度相应的从1下标开始
for(int i = len; i >= 1; i --)
{
for(int j = 0; j < 26; j ++)
{
nxt[i - 1][j] = nxt[i][j];//str i-1位置继承str i位置的离其它字符最近的位置是第几个
num[i-1][j]=num[i][j];
}
nxt[i - 1][str[i] - 'a'] = i;// str i-1位置离str[i]字符的最近位置变为第i个.
num[i-1][str[i] - 'a']++;
}
}
bool check(int x,int y,int t)
{
if(vis[y]+1>r[y]) return 0; //超过上限
vis[y]++;
int need=0;
int now=nxt[t][y];
if(now==0)
{
vis[y]--;
return 0;
}
for(int i=0;i<26;i++)
{
need+=max(0,l[i]-vis[i]);
}
if(need>k-x)
{
vis[y]--;
return 0;
}
for(int i=0;i<26;i++)
{
if(vis[i]+num[now][i]<l[i])
{
vis[y]--;
return 0;
}
}
return 1;
}
int main()
{
while(~scanf(" %s %d", str + 1,&k))
{
getnext(); //获得序列自动机的next数组
for(int i=0;i<26;i++)
scanf("%d%d",&l[i],&r[i]);
int pre=0,gg=0;
for(int i=1;i<=k;i++)
{
int flag=0;
for(int j=0;j<26;j++)
{
if(check(i,j,pre))
{
pre=nxt[pre][j];
ans[i]=j+'a';
flag=1;
break;
}
}
if(!flag)
{
gg=1;
break;
}
}
if(gg)
puts("-1");
else
{
ans[k+1]='\0';
printf("%s\n",ans+1);
}
} return 0;
}

2019 Multi-University Training Contest 1 String(序列自动机+贪心)的更多相关文章

  1. 2018 Multi-University Training Contest 1 Distinct Values 【贪心 + set】

    任意门:http://acm.hdu.edu.cn/showproblem.php?pid=6301 Distinct Values Time Limit: 4000/2000 MS (Java/Ot ...

  2. Hdu 4681 2013 Multi-University Training Contest 8 String

    带跨越式的LCS,同样是在朴素的LCS上加入一种跨越一段的转移,这样我们要预处理出跨越一段给定串的转移函数. 这个题同样可以正反两边LCS做 呆马: #include <iostream> ...

  3. 2019 Nowcoder Multi-University Training Contest 4 E Explorer

    线段树分治. 把size看成时间,相当于时间 $l$ 加入这条边,时间 $r+1$ 删除这条边. 注意把左右端点的关系. #include <bits/stdc++.h> ; int X[ ...

  4. 2019 Nowcoder Multi-University Training Contest 1 H-XOR

    由于每个元素贡献是线性的,那么等价于求每个元素出现在多少个异或和为$0$的子集内.因为是任意元素可以去异或,那么自然想到线性基.先对整个集合A求一遍线性基,设为$R$,假设$R$中元素个数为$r$,那 ...

  5. 2019 Multi-University Training Contest 4.Divide the Stones(贪心)

    题意:给你n和k (k|n) 有n个数 第i个数权值为i 要你求权值相同且分成k组 且每组的个数为n/k 思路:恶心构造题,首先对于总权值不能分为k份的 显然不能分成 然后 我们把n/k 分奇偶 我们 ...

  6. 2018 Multi-University Training Contest 1 Balanced Sequence(贪心)

    题意: t组测试数据,每组数据有 n 个只由 '(' 和 ')' 构成的括号串. 要求把这 n 个串排序然后组成一个大的括号串,使得能够匹配的括号数最多. 如()()答案能够匹配的括号数是 4,(() ...

  7. 2015 Multi-University Training Contest 8 hdu 5385 The path

    The path Time Limit: 2000ms Memory Limit: 65536KB This problem will be judged on HDU. Original ID: 5 ...

  8. 2019 Multi-University Training Contest 1

    2019 Multi-University Training Contest 1 A. Blank upsolved by F0_0H 题意 给序列染色,使得 \([l_i,r_i]\) 区间内恰出现 ...

  9. 2019 Multi-University Training Contest 2

    2019 Multi-University Training Contest 2 A. Another Chess Problem B. Beauty Of Unimodal Sequence 题意 ...

随机推荐

  1. CentOS7 安装frp与开机启动

    1. 下载frp程序文件 https://github.com/fatedier/frp/releases 2. 解压文件 下载后解压到自己的目录,我这里解压到/usr/local/frp: 3. 添 ...

  2. Python list遍历remove()时的一个小BUG

    有这样一个列表: s=list('abcdefg') 现在因为某种原因我们需要从s中踢出一些不需要的元素,方便起见这里直接以踢出所有元素的循环代替: for e in s: s.remove(e) 结 ...

  3. python创建文件夹

    import os filePath = 'D:\12345' # 判断文件夹是否存在,不存在则创建文件夹if not os.path.exists(filePath): os.makedirs(fi ...

  4. python2 和 python3共存的常见使用(如安装虚拟环境的问题)

    1.安装好python2和python3,配置好全部环境变量 环境变量修改后,需要重新启动命令行才有效 2.如何启动不同版本的python 启动的时候会执行python.exe,python2和pyt ...

  5. HTTPS混合内容解析

    什么是HTTPS混合内容 我们可能会有这样的经验,当我们通过HTTPS访问一个网站的时候,突然有提示:“本页面包含有不安全的内容”.这个时候会询问是否显示“不安全的内容”,这个时候,就是遇到了有混合内 ...

  6. Vue你不知到的$this.emit()的用法

    需求 需求:除了拿到false,还要拿到v-for中的index 如何解决:再使用一次父传子,:a="index" 将下标值传递给子组件   注意要加引号   <expert ...

  7. MYSQL 命令导出事件、存储过程、触发器

    普通导出某个数据库 mysqldump -u username -p passowrd databasename > file.sql 顺便导出事件 使用 –events 参数 mysqldum ...

  8. 201871010126 王亚涛《面向对象程序设计 JAVA》 第十三周学习总结

      内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p/ ...

  9. ASM与ASMD

    时序机 状态机 控制器 数据通路之间的关系 样例代码

  10. vue--npm的使用

    npm介绍 NPM 全称 Node Package Manager,它是 JavaScript 的包管理工具, 并且是 Node.js 平台的默认包管理工具.通过NPM 可以安装.共享.分发代码,管理 ...