题意

链接: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;
}

最新文章

  1. 深入学习jQuery选择器系列第一篇——基础选择器和层级选择器
  2. 编辑 Ext 表格(一)——— 动态添加删除行列
  3. bootstrap-datetime 的使用
  4. PHP批量删除做法
  5. 从几篇文字得到关于web app开发的性能问题的答案
  6. HDOJ 2066 floyed优化算法
  7. im4java开发向导
  8. ***ECharts图表入门和最佳实践
  9. QML定时器
  10. 调试NodeJS应用
  11. 【宽搜】ECNA 2015 D Rings (Codeforces GYM 100825)
  12. Visual Studio 2015开发Android App问题集锦
  13. iOS开发——NSDate(待续...)
  14. redis 2 字符串 和 hash
  15. 非关系型数据库redis-java基本操作
  16. bzoj 1558: [JSOI2009]等差数列
  17. 从Random Walk谈到Bacterial foraging optimization algorithm(BFOA),再谈到Ramdom Walk Graph Segmentation图分割算法
  18. JFinal提示:java.lang.RuntimeException: dao 只允许调用查询方法
  19. Java的map键值对的用法,map的遍历,Entry对象的使用
  20. visual studio2013 php

热门文章

  1. Good start is a half success(2019-04-07)
  2. Raspberry Pi (树莓派) 更换源 - stretch 版本
  3. 渗透测试学习 二十九、kali安装,信息搜集,服务器扫描
  4. fallowing-travelvue
  5. jinja2模板用法
  6. 加速自己的hexo,使用GitHub+Coding实现国内外网站加速
  7. 【Excel】对比两列值
  8. 2019 SDN上机第7次作业
  9. hebust-fengyu
  10. linux下通过命令行把文件拷贝到U盘上