题意

链接: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. python监控cpu 硬盘 内存

    import psutil import time import yagmail def sendmail(subject,contents): yag = yagmail.SMTP(user='15 ...

  2. 线性代数笔记24——微分方程和exp(At)

    原文:https://mp.weixin.qq.com/s/COpYKxQDMhqJRuMK2raMKQ 微分方程指含有未知函数及其导数的关系式,解微分方程就是找出未知函数.未知函数是一元函数的,叫常 ...

  3. Python踩坑系列之使用redis报错:module 'redis' has no attribute 'Redis'问题

    初次使用redis时,在链接Redis后,运行报错“module 'redis' has no attribute 'Redis' ”. 具体代码如下: import redis r = redis. ...

  4. MongoDB学习笔记(一、MongoDB入门)

    目录: 为什么要使用nosql mongo的简介 应用场景 入门demo 为什么要使用nosql: 随着互联网的发展,用户数量激增,访问量的上涨,传统的关系型数据库的性能也趋于瓶颈. 关系型数据库难以 ...

  5. (转)vue-router原理

    转载地址:https://segmentfault.com/a/1190000014822765 随着前端应用的业务功能起来越复杂,用户对于使用体验的要求越来越高,单面(SPA)成为前端应用的主流形式 ...

  6. 2019-2020-1 20199305《Linux内核原理与分析》第四周作业

    MenuOS的构造 一.Linux源代码的关键目录 block:存放块设备管理代码: crypto:存放常见加密算法的C语言代码: Documentation:存放一些文档: drivers:驱动目录 ...

  7. ubuntu下使用redshift开启护眼模式

    前面提到flux这东西在一些机器上并不能work,而且也找到了一些关于他不能work的线索(戳这里看原因).根据这些线索我们发现用flux不行了,得换用redshift,那好吧,我们就来装redshi ...

  8. BoW算法及DBoW2库简介(二)

    一.BoW算法 用OpenCV实现了最简单的BoW算法进行了一次小规模的图像检索任务,使用UKbench数据库,算法原理和网上的描述差不多,使用K-means算法进行聚类,这里使用KDTree算法进行 ...

  9. 使用OC实现单链表:创建、删除、插入、查询、遍历、反转、合并、判断相交、求成环入口

    一.概念 链表和数组都是一种线性结构,数组有序存储的,链表是无序存储的. 数组中的每一个元素地址是递增或者递减的关系,链表的每一个节点的地址没有此规律,它们是通过指针的指向连接起来. 链表种类:单链表 ...

  10. Java Arrays类方法

    1:概述 主要谈一谈 Java使用fork/koin类 实现的并发排序 以及对于Stream流的支持的splitetor mismatch()   ->  寻找两个数组 第一次出现数据不一致的下 ...