bzoj 3214: [Zjoi2013]丽洁体

Description

平时的练习和考试中,我们经常会碰上这样的题:命题人给出一个例句,要我们类比着写句子。这种往往被称为仿
写的题,不单单出现在小学生的考试中,也有时会出现在中考中。许多同学都喜欢做这种题,因为较其它题显得有
趣。仿写的句子往往具有“A__B__C”的形式,其中A,B,C是给定的由一个或多个单词组成的短句,空的部分需要
学生填写。当然,考试的时候空在那里也是可以的。例如,“其实天不暗阴云终要散,其实 ,其实 ,其实路不远
一切会如愿,艰难困苦的日子里我为你祈祷,请你保重每一天”。再比如,“见了大海的汹涌,没见过大山的巍峨
,真是遗憾;见了大山的巍峨,没见过 ,还是遗憾。出发吧,永远出发。 ,人有不老的心情。”由于现在是网络
时代,我们不再只能仿写命题人命的题,我们可以仿写网上各种句子和段落。2011年3月26日,某人在博客上发布
了的消息就惹来了很多人的仿写。
很难过吧。。。考得完爆了。。。
。。。。。。其实也没什么可以说的。。。都是蒟蒻的借口罢了。。。
。。。自己果然还只是半吊子水平呢。。。。
。。。祝大家都能进省队。。。其实只要不要有遗憾就好了呢。。。
虽然我很遗憾或许不能走下去了。。。。。
886
在网络上广泛流传的仿写,因为在某些地方有独到之处,大都被命名为“某某体”。打开人人,刷新微博,你也能
发现这样和那样的体,比如,对不起体,**说明他爱你体等等。金先生注意到了这一现象,他敏锐地认为这是一个
很有价值的研究课题,于是就其展开研究,打算发一篇paper。由于在网上发消息,人们有了更大的灵活度,人们
有时因为表达的需要,还往原本固定的A, B, C中添加一些修饰的词语。这就给辨别一个句子或段落是否是另一个
句子或段落的仿写增加了困难。金先生现在研究一种形如“ABC”的体作品,其中A, B, C分别是某个由若干单词
组成的短句,*代表0个或多个单词。他在网上找了大量的体作品,不过很多体作品不太合乎原作者的格式,也就是
相当于在正规的体作品中插入了0个或多个单词。由于数据量太大,金先生无法一个一个看过去,于是想请你帮忙
,去掉尽量少的单词,使它成为指定的体。

Solution

首先对于A,C串可以直接贪心求出来,左右两边单调指针分别扫一下即可
对于B串,也就是要找到一个子序列使得B是它的子串,并最小化这个子序列
那么贪心即可
假设匹配的B的第 \(i\) 位,我们当然希望 \(i-1\) 位尽量近,所以维护这个东西即可
设\(f[i]\)表示第\(i\)位的字符最晚在 \(T\) 串的哪个位置出现
设\(g[i]\)表示匹配前 \(i\) 位最少删除的字符
因为每个单词出现次数比较少,所以可以直接遍历 \(B\) 串的这个单词,把B的每一个单词出现的位置挂链即可
注意读入很坑的.....

#include<bits/stdc++.h>
using namespace std;
const int N=250010,M=15000000;
char S[M];int s[N],a[N],b[N],c[N],f[N],g[N];
vector<int>e[M];
void init(int *p){
    char ch=getchar();int len=0;
    while(ch!='\n')S[++len]=ch,ch=getchar();
    for(int i=1,j;i<=len;i=j+1){
        int t=0;j=i;
        while(S[j]>='a' && S[j]<='z')t=t*27+S[j]-'a'+1,j++;
        p[++p[0]]=t;
    }
}
int main(){
  freopen("pp.in","r",stdin);
  freopen("pp.out","w",stdout);
  init(s);init(a);init(b);init(c);
  int l=1,r=s[0],x=1,sum=0,ans=2e8;
  while(x<=a[0]){
      while(l<=s[0] && a[x]!=s[l])l++,sum++;
      x++;l++;
  }
  x=c[0];
  while(x>=1){
      while(r>=1 && c[x]!=s[r])r--,sum++;
      x--;r--;
  }
  memset(g,127/3,sizeof(g));
  for(int i=1;i<=b[0];i++)e[b[i]].push_back(i);
  for(int i=l;i<=r;i++){
      for(int j=e[s[i]].size()-1;j>=0;j--){
          x=e[s[i]][j];
          if(x==1)f[x]=i,g[x]=0;
          else if(f[x-1])f[x]=i,g[x]=g[x-1]+i-f[x-1]-1;
          ans=min(ans,g[b[0]]);
      }
  }
  cout<<sum+ans<<endl;
  return 0;
}

原文地址:https://www.cnblogs.com/Yuzao/p/8458356.html

时间: 2024-11-13 10:42:07

bzoj 3214: [Zjoi2013]丽洁体的相关文章

【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$

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

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

[ZJOI2013]丽洁体

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

并不对劲的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\

树套树专题——bzoj 3110: [Zjoi2013] K大数查询 &amp; 3236 [Ahoi2013] 作业 题解

[原题1] 3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 978  Solved: 476 Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c 如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是多少. Input 第一行N,M 接下来M行,每行形如1 a b c或2 a b c Outpu

BZOJ 3110: [Zjoi2013]K大数查询( 树状数组套主席树 )

BIT+(可持久化)权值线段树, 用到了BIT的差分技巧. 时间复杂度O(Nlog^2(N)) ----------------------------------------------------------------------------------------- #include<cstdio> #include<cctype> #include<cstring> #include<algorithm> using namespace std;

BZOJ 3110: [Zjoi2013]K大数查询 [树套树]

3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 6050  Solved: 2007[Submit][Status][Discuss] Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是多少. Input 第一行N,M接下来M行,每行形如1 a

[BZOJ 3110] [Zjoi2013] K大数查询 【树套树】

题目链接: BZOJ - 3110 题目分析 这道题是一道树套树的典型题目,我们使用线段树套线段树,一层是区间线段树,一层是权值线段树.一般的思路是外层用区间线段树,内层用权值线段树,但是这样貌似会很难写.多数题解都使用了外层权值线段树,内层区间线段树,于是我就这样写了.每次插入会在 logn 棵线段树中一共建 log^2(n) 个结点,所以空间应该开到 O(nlog^2(n)) .由于这道题查询的是区间第 k 大,所以我们存在线段树中的数值是输入数值的相反数(再加上 n 使其为正数),这样查第

BZOJ 3112: [Zjoi2013]防守战线 [单纯形法]

题目描述 战线可以看作一个长度为n 的序列,现在需要在这个序列上建塔来防守敌兵,在序列第i 号位置上建一座塔有Ci 的花费,且一个位置可以建任意多的塔,费用累加计算.有m 个区间[L1, R1], [L2, R2], …, [Lm, Rm],在第i 个区间的范围内要建至少Di 座塔.求最少花费. 输入输出格式 输入格式: 第一行为两个数n, m. 接下来一行,有n 个数,描述C 数组. 接下来m 行,每行三个数Li,Ri,Di,描述一个区间. 输出格式: 仅包含一行,一个数,为最少花费. 输入输