博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CF1083B The Fair Nut and String
阅读量:4656 次
发布时间:2019-06-09

本文共 985 字,大约阅读时间需要 3 分钟。

题意

给出两个长度为n的01字符串S和T。
选出k个字典序在S和T之间的长度为n的01字符串,使得尽可能多的字符串满足其是所选字符串中至少一个串的前缀。

这是一道思路比较奇怪的类似计数dp的题。

首先考虑如果把选出的这些串插入到一个trie树中的话,算产生的贡献可以理解为,从根节点向下画了k条长度为n的线,最大化它们所经过的点的总个数。

进一步发现,每一层节点如果不受s和t的限制的话,一定可以满足每一层都有k个点被经过。

因此,剩下要做的就是算一下这个s和t的限制,即每一层有多少个节点。

记dp[i][0/1][0/1]表示第i层,满足前i位是否与s相同,前i位是否与t相同,按照定义转移即可,复杂度O(n)。

最后统计答案的时候把每一层的节点个数和k取min后加入答案即可。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#define N 1100000#define L 1000000#define eps 1e-7#define ll long longusing namespace std;inline ll read(){ char ch=0; ll x=0,flag=1; while(!isdigit(ch)){ch=getchar();if(ch=='-')flag=-1;} while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();} return x*flag;}const ll inf=1e14+7;char s[N],t[N];ll dp[N][2][2];int main(){ ll n=read(),m=read(); scanf("%s",s+1);scanf("%s",t+1); dp[0][1][1]=1; for(ll i=0;i

转载于:https://www.cnblogs.com/Creed-qwq/p/10105996.html

你可能感兴趣的文章
会话记住已登录功能
查看>>
Linux内核分析——可执行程序的装载
查看>>
第一阶段冲刺3
查看>>
父类引用指向子类对象
查看>>
网页如何实现下载功能
查看>>
IT男专用表白程序
查看>>
读《大道至简》第六章感想
查看>>
ef linq 中判断实体中是否包含某集合
查看>>
章三 链表
查看>>
Solution for Concurrent number of AOS' for this application exceeds the licensed number
查看>>
CSE 3100 Systems Programming
查看>>
IntelliJ IDEA 的Project structure说明
查看>>
Java Security(JCE基本概念)
查看>>
Linux Supervisor的安装与使用入门
查看>>
创建 PSO
查看>>
JasperReport报表设计4
查看>>
项目活动定义 概述
查看>>
团队冲刺04
查看>>
我的Python分析成长之路8
查看>>
泛型在三层中的应用
查看>>