并不对劲的bzoj3214:p3333:[ZJOI2013]丽洁体

题目大意

有三个由若干个单词组成的字符串\(T,A,B,C(|T|,|A|,|B|,|C|\leq 5*10^4,单词长度\leq5,每个单词出现次数\leq500)\)

求从\(T\)中至少删去多少个单词,使\(T\)变成\(A*B*C\)的形式,其中\(*\)可以用若干个单词替换,输入数据保证有解

题解

发现删去若干个单词后,一个前缀变成了\(A\),一个后缀变成了\(C\),那么找到最短的有\(A\)为子序列的前缀和最短的有\(C\)为子序列的后缀就行

在剩下的部分中,找到最短的以\(B\)为子序列的子串

\(B\)中的第一个单词只出现了不超过\(500\)次,那么就可以先枚举起点,再用上面的方法贪心

时间复杂度\(\Theta(|T|*(B的第一个单词出现次数))\)

代码
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<iomanip>
#include<iostream>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
#define rep(i,x,y) for(register int i=(x);i<=(y);++i)
#define dwn(i,x,y) for(register int i=(x);i>=(y);--i)
#define maxn 50001
#define maxm 501
#define LL long long
#define UI unsigned int
using namespace std;
int read()
{
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)&&ch!=‘-‘)ch=getchar();
    if(ch==‘-‘)f=-1,ch=getchar();
    while(isdigit(ch))x=(x<<1)+(x<<3)+ch-‘0‘,ch=getchar();
    return x*f;
}
void write(int x)
{
    if(x==0){putchar(‘0‘),putchar(‘\n‘);return;}
    int f=0;char ch[20];
    if(x<0)putchar(‘-‘),x=-x;
    while(x)ch[++f]=x%10+‘0‘,x/=10;
    while(f)putchar(ch[f--]);
    putchar(‘\n‘);
    return;
}
char s[10],c;
UI t[maxn],a[2][maxn],b[maxn];
int len,lent,lena[2],lenb,hd,tl,fakeans,ansb=2147483647;
UI hsh()
{
    UI res=0,now=1;
    rep(i,1,len){if(s[i]<‘a‘||s[i]>‘z‘)break;res+=now*(UI)(s[i]-‘a‘+1),now=now*(UI)27;}
    return res;
}
int getstr(UI * u)
{
    int lenu=0;
    do
    {
        len=0;c=getchar();
        while(c==‘ ‘||c==‘\n‘)c=getchar();
        while(c!=‘ ‘&&c!=‘\n‘)s[++len]=c,c=getchar();
        u[++lenu]=hsh();
    }while(c!=‘\n‘);
    return lenu;
}
int main()
{
    lent=getstr(t),lena[0]=getstr(a[0]),lenb=getstr(b),lena[1]=getstr(a[1]);
    int j=0;
    rep(i,1,lent)
    {
        if(t[i]==a[0][j+1])j++;
        if(j==lena[0]){hd=i+1;fakeans=i-j;break;}
    }j=lena[1]+1;
    dwn(i,lent,1)
    {
        if(t[i]==a[1][j-1])j--;
        if(j==1){tl=i-1;fakeans+=lent-i+1-lena[1];break;}
    }
    rep(i,hd,tl)
        if(t[i]==b[1])
        {
            int j=1;
            rep(k,i+1,tl)
            {
                if(t[k]==b[j+1])j++;
                if(j==lenb){ansb=min(ansb,k-i+1-j);break;}
            }
        }
    write(fakeans+ansb);
    return 0;
}

原文地址:https://www.cnblogs.com/xzyf/p/10423620.html

时间: 2024-10-29 09:00:45

并不对劲的bzoj3214:p3333:[ZJOI2013]丽洁体的相关文章

[luogu] P3333 [ZJOI2013]丽洁体(贪心)

P3333 [ZJOI2013]丽洁体 题目描述 平时的练习和考试中,我们经常会碰上这样的题:命题人给出一个例句,要我们类比着写句子.这种往往被称为仿写的题,不单单出现在小学生的考试中,也有时会出现在中考中.许多同学都喜欢做这种题,因为较其它题显得有趣.仿写的句子往往具有"A__B__C"的形式,其中A,B,C是给定的由一个或多个单词组成的短句,空的部分需要学生填写.当然,考试的时候空在那里也是可以的.例如,"其实天不暗阴云终要散,其实 ,其实 ,其实路不远一切会如愿,艰难困

【BZOJ】3214: [Zjoi2013]丽洁体

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3214 字符串长度最大不超过$5$直接$HASH$起来 首先在$T$中考虑找到最前的一个包含$A$的子序列,找到最后的一个包含$C$的子序列,直接贪心的确定了$A,C$的位置. 在剩下的区间内$DP$出最合适的$B$的位置. 我们要找到一个区间${[l,r]}$使得$B$是它的子序列,显然应该最小化$r-l$. 令$F[i]$表示$B$中第$i$单词最晚出现的位置. $g[i]$表示$B$

bzoj 3214: [Zjoi2013]丽洁体

Description 平时的练习和考试中,我们经常会碰上这样的题:命题人给出一个例句,要我们类比着写句子.这种往往被称为仿 写的题,不单单出现在小学生的考试中,也有时会出现在中考中.许多同学都喜欢做这种题,因为较其它题显得有 趣.仿写的句子往往具有"A__B__C"的形式,其中A,B,C是给定的由一个或多个单词组成的短句,空的部分需要 学生填写.当然,考试的时候空在那里也是可以的.例如,"其实天不暗阴云终要散,其实 ,其实 ,其实路不远 一切会如愿,艰难困苦的日子里我为你祈

[ZJOI2013]丽洁体

题目描述 平时的练习和考试中,我们经常会碰上这样的题:命题人给出一个例句,要我们类比着写句子.这种往往被称为仿写的题,不单单出现在小学生的考试中,也有时会出现在中考中.许多同学都喜欢做这种题,因为较其它题显得有趣.仿写的句子往往具有“A__B__C”的形式,其中A,B,C是给定的由一个或多个单词组成的短句,空的部分需要学生填写.当然,考试的时候空在那里也是可以的.例如,“其实天不暗阴云终要散,其实 ,其实 ,其实路不远一切会如愿,艰难困苦的日子里我为你祈祷,请你保重每一天”.再比如,“见了大海的

《1024伐木累》-小白篇之丽jie(结束篇)-总章节六

往期回顾:  机缘巧合,月侠发现了老王和他心仪女孩儿的秘密,这让他倍感愤怒,一年以后,丽姐又在去往老王家的路上,这让月侠感到历史即将重新上演,他想拦住丽姐,可恰巧丽姐手机没电,失去了联系. 小序 有人天生热心肠, 他人见怪莫管闲, 竖起拇指空赞叹, 社会冷漠妄悲欢. 社会.职场人情冷暖, 各家自扫门前雪,不问他人瓦上霜. 沉睡的良知,何时才能唤醒? 引子 老王喜欢韩剧,泡泡剧的浪漫让他着迷,耗仔还因为这事儿取笑过他,但他不以为然,喜欢是天生的,不会因为什么而改变. 对待女孩儿,老王很舍得花钱.身

SPOJ8222 Substrings( 后缀自动机 + dp )

题目大意:给一个字符串S,令F(x)表示S的所有长度为x的子串中,出现次数的最大值.F(1)..F(Length(S)) 建出SAM, 然后求出Right, 求Right可以按拓扑序dp..Right就是某个点到结束状态的路径数, parent树上last的那一条链都是结束状态...然后用Right去更新答案.. spoj卡常数..一开始用DFS就炸了, 改用BFS就A了.. (贴一下丽洁姐的题解: 我们构造S的SAM,那么对于一个节点s,它的长度范围是[Min(s),Max(s)],同时他的出

BZOJ3926 ZJOI2015 诸神眷顾的幻想乡 后缀自动机+DFS

题意:给定一颗字符树,求树中路径所构成的不同的字符串的数量,其中AB和BA视作不同的字符串 题解: 题目里有这样一句话:太阳花田的结构比较特殊,只与一个空地相邻的空地数量不超过20个. 一共有10W个点,却只有20个叶子……因此树上所有的字串就是以叶子为起点搜索出的所有字串,丽洁姐真的好善良啊- -(无雾) 这样从每个点开始就能跑出来一颗Trie树,对Trie构造广义后缀自动机——每个节点看成是一个根,在后面加字符的时候和普通的SAM一样. 然后在SAM上用DFS统计不同字串的数量即可 #inc

3153: Sone1

这题网上题解比决战好像要多23333 先丢链接跪四位大爷 http://blog.csdn.net/iamzky/article/details/43494481 虽然理解之后大家都讲得很清晰 不过窝看了很久都木有看懂Orz 于是此篇题解尽量平易近人一些吧 窝突然想到一定会有人怀疑我做这种无脑数据结构题的意义…… 于是:我的人生,一片无悔~ ~~~~~吐槽时间~~~~~ 觉得杜教写法不太自然,然后写了个自然的,但是因为要维护子树信息……果断被教做人了 我猜我得调到十点了.一语成谶! 最后甚至都把

[BZOJ 1084][SCOI2005]最大子矩阵

Description 这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大.注意:选出的k个子矩阵不能相互重叠. Input 第一行为n,m,k(1≤n≤100,1≤m≤2,1≤k≤10),接下来n行描述矩阵每行中的每个元素的分值(每个元素的分值的绝对值不超过32767). Output 只有一行为k个子矩阵分值之和最大为多少. Sample Input 3 2 2 1 -3 2 3 -2 3 Sample Output 9 HINT Source 刚开始没看清题,以