CF 1400F.x-prime Substrings

题意:

给定一个由\('1'\)到\('9'\)组成的字符串\(s\)和一个数\(x\),定义一个串为\(x-prime\)串,当且仅当这个串上的数字和为\(x\),且任意一个不等于本身的子串的和都不是\(x\)的因子,问最少删多少个数字可以使得串\(s\)的任何子串都不是\(x-prime\)串

\(1 \le |s| \le 1000,1 \le x \le 20\)

题解:

由于\(x\)很小,所以我们可以枚举所有\(x-prime\)串,然后把所有的\(x-prime\)串放到\(Trie\)里面去,因为我们需要原串中没有\(x-prime\)串,考虑把所有\(x-prime\)串建AC自动机,然后我们跑一遍\(dp\),\(dp[i][j]\)表示\(s\)串中的第\(i\)位匹配了自动机上的状态\(j\)的情况下的最小删除数量

枚举自动机所有的状态\(j\),那么存在两种转移:

  1. 删除下一个点,\(dp[i][j] = min(dp[i][j],dp[i-1][j]+1)\)
  2. 走到自动机的下一个点,\(dp[i][trans[j]] = min(dp[i][trans[j],dp[i-1][j])\)

其中第二种转移必须要求AC自动机的下一个点没有匹配到任何的\(x-prime\)串

由于每个状态只与上一层有关,可以把\(dp\)数组变为滚动数组

那么,这道题就完成了

view code

#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast,no-stack-protector")
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define endl "\n"
#define LL long long int
#define vi vector<int>
#define vl vector<LL>
#define all(V) V.begin(),V.end()
#define sci(x) scanf("%d",&x)
#define scl(x) scanf("%I64d",&x)
#define scs(x) scanf("%s",s)
#define pii pair<int,int>
#define pll pair<LL,LL>
#ifndef ONLINE_JUDGE
#define cout cerr
#endif
#define cmax(a,b) ((a) = (a) > (b) ? (a) : (b))
#define cmin(a,b) ((a) = (a) < (b) ? (a) : (b))
#define debug(x) cerr << #x << " = " << x << endl
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
template <typename T> vector<T>& operator << (vector<T> &__container, T x){ __container.push_back(x); return __container; }
template <typename T> ostream& operator << (ostream &out, vector<T> &__container){ for(T _ : __container) out << _ << ' '; return out; }
const int MAXN = 1111;
struct AC_automaton{
int ch[MAXN<<5][9],fail[MAXN<<5],tot;
bool tag[MAXN<<5];
void insert(string s){
int p = 0;
for(int i = 0; i < (int)s.size(); i++){
int c = s[i] - '1';
if(!ch[p][c]) ch[p][c] = ++tot;
p = ch[p][c];
}
tag[p] = true;
}
void build_fail(){
queue<int> que;
for(int i = 0; i < 9; i++) if(ch[0][i]) que.push(ch[0][i]);
while(!que.empty()){
int u = que.front();
que.pop();
for(int i = 0; i < 9; i++){
if(!ch[u][i]) { ch[u][i] = ch[fail[u]][i]; continue; }
que.push(ch[u][i]);
int v = ch[u][i];
int pre = fail[u];
while(pre and !ch[pre][i]) pre = fail[pre];
fail[v] = ch[pre][i];
tag[v] |= tag[fail[v]];
}
}
}
int DP(string &s){
vector<int> f(tot+1,INF);
f[0] = 0;
for(char &c : s){
int x = c - '1';
vector<int> next_f(tot+1,INF);
for(int i = 0; i <= tot; i++){
if(f[i]==INF) continue;
cmin(next_f[i],f[i]+1);
if(!tag[ch[i][x]]) cmin(next_f[ch[i][x]],f[i]);
}
f.swap(next_f);
}
return *min_element(all(f));
}
}aho; bool check(string &dig, int x){
vector<int> pre(dig.size());
pre[0] = dig[0] - '0';
for(int i = 1; i < (int)dig.size(); i++) pre[i] = pre[i-1] + dig[i] - '0';
for(int i = 0; i < (int)dig.size(); i++){
for(int j = i; j < (int)dig.size(); j++){
int S = pre[j] - (i==0?0:pre[i-1]);
if(S!=x and x%S==0) return false;
}
}
return true;
}
void search_dig_string(string &dig, int sum, int x){
if(sum==x){
if(check(dig,x)) aho.insert(dig);
return;
}
for(int i = 1; i < 10; i++){
if(sum+i>x) return;
dig.push_back(i+'0');
search_dig_string(dig,sum+i,x);
dig.pop_back();
}
}
void solve(){
string str;
int x;
cin >> str >> x;
string dig("");
search_dig_string(dig,0,x);
aho.build_fail();
cout << aho.DP(str) << endl;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
solve();
return 0;
}

CF 1400F x-prime Substrings 题解【AC自动机+DP】的更多相关文章

  1. 【bzoj1030】[JSOI2007]文本生成器 AC自动机+dp

    题目描述 JSOI交给队员ZYX一个任务,编制一个称之为“文本生成器”的电脑软件:该软件的使用者是一些低幼人群,他们现在使用的是GW文本生成器v6版.该软件可以随机生成一些文章―――总是生成一篇长度固 ...

  2. HDU 2457 DNA repair(AC自动机+DP)题解

    题意:给你几个模式串,问你主串最少改几个字符能够使主串不包含模式串 思路:从昨天中午开始研究,研究到现在终于看懂了.既然是多模匹配,我们是要用到AC自动机的.我们把主串放到AC自动机上跑,并保证不出现 ...

  3. HDU2296——Ring(AC自动机+DP)

    题意:输入N代表字符串长度,输入M代表喜欢的词语的个数,接下来是M个词语,然后是M个词语每个的价值.求字符串的最大价值.每个单词的价值就是单价*出现次数.单词可以重叠.如果不止一个答案,选择字典序最小 ...

  4. 【BZOJ】4861: [Beijing2017]魔法咒语 AC自动机+DP+矩阵快速幂

    [题意]给定n个原串和m个禁忌串,要求用原串集合能拼出的不含禁忌串且长度为L的串的数量.(60%)n,m<=50,L<=100.(40%)原串长度为1或2,L<=10^18. [算法 ...

  5. 【hdu2457】ac自动机 + dp

    传送门 题目大意: 给你一个字符主串和很多病毒串,要求更改最少的字符使得没有一个病毒串是主串的子串. 题解: ac自动机 + dp,用病毒串建好ac自动机,有毒的末尾flag置为true 构建fail ...

  6. luoguP5319 [BJOI2019]奥术神杖(分数规划,AC自动机DP)

    luoguP5319 [BJOI2019]奥术神杖(分数规划,AC自动机DP) Luogu 题解时间 难点在于式子转化,设有c个满足的子串,即求最大的 $ ans = \sqrt[c]{\prod_{ ...

  7. POJ1625 Censored!(AC自动机+DP)

    题目问长度m不包含一些不文明单词的字符串有多少个. 依然是水水的AC自动机+DP..做完后发现居然和POJ2778是一道题,回过头来看都水水的... dp[i][j]表示长度i(在自动机转移i步)且后 ...

  8. HDU2296 Ring(AC自动机+DP)

    题目是给几个带有价值的单词.而一个字符串的价值是 各单词在它里面出现次数*单词价值 的和,问长度不超过n的最大价值的字符串是什么? 依然是入门的AC自动机+DP题..不一样的是这题要输出具体方案,加个 ...

  9. HDU2457 DNA repair(AC自动机+DP)

    题目一串DNA最少需要修改几个基因使其不包含一些致病DNA片段. 这道题应该是AC自动机+DP的入门题了,有POJ2778基础不难写出来. dp[i][j]表示原DNA前i位(在AC自动机上转移i步) ...

  10. hdu 4117 GRE Words AC自动机DP

    题目:给出n个串,问最多能够选出多少个串,使得前面串是后面串的子串(按照输入顺序) 分析: 其实这题是这题SPOJ 7758. Growing Strings AC自动机DP的进阶版本,主题思想差不多 ...

随机推荐

  1. ssh升级以及ssh: symbol lookup error: ssh: undefined symbol: EVP_aes_128_ctr错误处理

    1.解压安装openssl包:(不能卸载openssl,否则会影响系统的ssl加密库文件,除非你可以做两个软连接libcryto和libssl) # tar -zxvf openssl-1.0.1.t ...

  2. 使用Python自动填写问卷星(pyppeteer反爬虫版)

    写此文的目的是为了方便寒假自己忘记填问卷星 一开始的想法和去年一样,去年就写过一版,想着今年不过就是改改数据,换换id而已,另外没想到的事情发生了... 满怀信心的写完代码 from selenium ...

  3. leetcode-222完全二叉树的节点个数

    题目 给出一个完全二叉树,求出该树的节点个数. 说明: 完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置. ...

  4. (数据科学学习手札103)Python+Dash快速web应用开发——页面布局篇

    本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 这是我的系列教程Python+Dash快速web ...

  5. Openstack neutron 网络服务 (七)

    引用: https://docs.openstack.org/ocata/zh_CN/install-guide-rdo/common/get-started-networking.html neut ...

  6. 数据库MySQL(带你零基础入门MySQL)

    (一)认识数据库 redis默认端口:6379 mysql默认端口:3306 什么是数据库? 数据库的英文单词:data base,简称DB. 数据库实际上就是一个文件集合,是一个存储数据的仓库,本质 ...

  7. Session、Cookie与Token

    http协议是无状态协议 协议是指计算机通信网络中两台计算机之间进行通信所必须共同遵守的规定或规则,超文本传输协议(HTTP)是一种通信协议,它允许将超文本标记语言(HTML)文档从Web服务器传送到 ...

  8. 【UML】Use Case Diagrams

    文章目录 Use Case Diagrams Introduction Use case Diagram Use Case Diagrams - Actors Use Case Diagrams – ...

  9. 【Docker】CentOS7 上无网络情况下安装

    自建虚拟机,但是连接不上网络,只能通过下载rpm包进行安装docker 环境:CentOS 7.3.1611 x64 rpm镜像下载地址用的阿里的https://mirrors.aliyun.com/ ...

  10. IP2723T中文规格书PDF

    IP2723T 是一款集成多种协议.用于 USB 输出端口的快充协议 IC.支持多种快充协议,包括 USBTypeC DFP,PD2.0/PD3.0/PPS,HVDCPQC4/QC4+/QC3.0/Q ...