[BZOJ5073] [Lydsy1710月赛]小A的咒语 后缀数组+dp+贪心

本文详细解析了BZOJ5073题目,采用动态规划和字符串匹配算法,通过计算最长公共前缀优化状态转移,实现高效求解。文章提供了完整的代码实现,包括后缀数组构造、LCP数组计算等关键步骤。

题目链接

首先这种题一看就是dp。

\(dp[i][j]\)表示\(A\)序列中到\(i\)位之前,取了\(j\)段,在\(B\)中的最长的长度。

转移也比较简单

\[ dp[i][j] \to dp[i+1][j] \quad \text{不选} \\ dp[i][j] \to dp[i+k][j+1] \quad a[i+1..i+k]=b[dp[i][j]..dp[i][j]+k] \]

但是这样做的复杂度肯定不行。

发现有一个贪心的思路,因为既然我这里已经占用了一次次数了,那么肯定要尽量地多在B中匹配才好。

所以这里的\(k\)可以直接取到\(LCP(a[i+1],b[dp[i][j]+1])\)。中间的点可以直接跳过,不用转移过去。

#include<bits/stdc++.h>
using namespace std;
#define fec(i,x,y) (int i=head[x],y=g[i].to;i;i=g[i].ne,y=g[i].to)
#define dbg(...) fprintf(stderr,__VA_ARGS__)
#define File(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
#define fi first
#define se second
#define pb push_back
template<typename I>inline void read(I&x){int f=0,c;while(!isdigit(c=getchar()))c=='-'?f=1:0;x=c&15;while(isdigit(c=getchar()))x=(x<<1)+(x<<3)+(c&15);f?x=-x:0;}
template<typename A,typename B>inline char SMAX(A&a,const B&b){return a<b?a=b,1:0;}
template<typename A,typename B>inline char SMIN(A&a,const B&b){return a>b?a=b,1:0;}
typedef long long ll;typedef unsigned long long ull;typedef std::pair<int,int>pii;

const int N=2e5+7,M=100+7,LOG=20;
int T,n,m,p,ans;char a[N],b[N],s[N];
int dp[N][M];

int sa[N],rk[N],sec[N],tax[N],h[N];
inline void Make_SA(char*s,int n){
    int m=26,*rnk=rk,*sc=sec;
    for(int i=1;i<=m;++i)tax[i]=0;
    for(int i=1;i<=n;++i)tax[rnk[i]=s[i]]++;
    for(int i=1;i<=m;++i)tax[i]+=tax[i-1];
    for(int i=n;i;--i)sa[tax[rnk[i]]--]=i;
    for(int k=1;k<=n;k<<=1){
        int p=0;
        for(int i=n-k+1;i<=n;++i)sc[++p]=i;
        for(int i=1;i<=n;++i)if(sa[i]>k)sc[++p]=sa[i]-k;
        for(int i=1;i<=m;++i)tax[i]=0;
        for(int i=1;i<=n;++i)tax[rnk[sc[i]]]++;
        for(int i=1;i<=m;++i)tax[i]+=tax[i-1];
        for(int i=n;i;--i)sa[tax[rnk[sc[i]]]--]=sc[i];
        swap(rnk,sc);p=rnk[sa[1]]=1;
        for(int i=2;i<=n;++i)rnk[sa[i]]=(sc[sa[i]]==sc[sa[i-1]]&&sc[sa[i]+k]==sc[sa[i-1]+k]?p:++p);
        if(p>=n)break;else m=p;
    }
    for(int i=1;i<=n;++i)rk[sa[i]]=i;
}
inline void Make_h(char*s,int n){
    for(int i=1,f=0;i<=n;++i){
        if(f)f--;int j=sa[rk[i]-1];
        while(i+f<=n&&j+f<=n&&s[i+f]==s[j+f])++f;
        h[rk[i]]=f;
    }
}

int f[N][LOG];
inline void RMQ_init(int n){
    for(int i=1;i<=n;++i)f[i][0]=h[i];
    for(int j=1;(1<<j)<=n;++j)
        for(int i=1;i+(1<<j)-1<=n;++i)
            f[i][j]=min(f[i][j-1],f[i+(1<<(j-1))][j-1]);
}
inline int Min(int l,int r){int k=__lg(r-l+1);return min(f[l][k],f[r-(1<<k)+1][k]);}
inline int LCP(int x,int y,int n=::n+m){if(x==y)return n-x+1;x=rk[x],y=rk[y];if(x>y)swap(x,y);return Min(x+1,y);}

inline void DP(){
    for(int i=0,k;i<n;++i)
        for(int j=0;j<=p;++j)
            SMAX(dp[i+1][j],dp[i][j]),
            k=min(n-i,LCP(i+1,dp[i][j]+n+1)),
            j<p&&SMAX(dp[i+k][j+1],dp[i][j]+k);
}

inline void CSH(){
    memset(dp,0,sizeof(dp));
    ans=0;
}
int main(){
    #ifdef hzhkk
    freopen("hkk.in","r",stdin);
    #endif
    read(T);
    while(T--){
        CSH();
        read(n),read(m),read(p);
        scanf("%s%s",a+1,b+1);
        for(int i=1;i<=n;++i)s[i]=a[i]-'a'+1;
        for(int i=1;i<=m;++i)s[i+n]=b[i]-'a'+1;
        Make_SA(s,n+m);Make_h(s,n+m);
        RMQ_init(n+m);
        DP();
        for(int i=1;i<=p;++i)SMAX(ans,dp[n][i]);
        if(ans>=m)printf("YES\n");
        else printf("NO\n");
    }
}

转载于:https://www.cnblogs.com/hankeke/p/BZOJ5073.html

内容概要:本文设计了一种基于PLC的全自动洗衣机控制系统内容概要:本文设计了一种,采用三菱FX基于PLC的全自动洗衣机控制系统,采用3U-32MT型PLC作为三菱FX3U核心控制器,替代传统继-32MT电器控制方式,提升了型PLC作为系统的稳定性与自动化核心控制器,替代水平。系统具备传统继电器控制方式高/低水,实现洗衣机工作位选择、柔和过程的自动化控制/标准洗衣模式切换。系统具备高、暂停加衣、低水位选择、手动脱水及和柔和、标准两种蜂鸣提示等功能洗衣模式,支持,通过GX Works2软件编写梯形图程序,实现进洗衣过程中暂停添加水、洗涤、排水衣物,并增加了手动脱水功能和、脱水等工序蜂鸣器提示的自动循环控制功能,提升了使用的,并引入MCGS组便捷性与灵活性态软件实现人机交互界面监控。控制系统通过GX。硬件设计包括 Works2软件进行主电路、PLC接梯形图编程线与关键元,完成了启动、进水器件选型,软件、正反转洗涤部分完成I/O分配、排水、脱、逻辑流程规划水等工序的逻辑及各功能模块梯设计,并实现了大形图编程。循环与小循环的嵌; 适合人群:自动化套控制流程。此外、电气工程及相关,还利用MCGS组态软件构建专业本科学生,具备PL了人机交互C基础知识和梯界面,实现对洗衣机形图编程能力的运行状态的监控与操作。整体设计涵盖了初级工程技术人员。硬件选型、; 使用场景及目标:I/O分配、电路接线、程序逻辑设计及组①掌握PLC在态监控等多个方面家电自动化控制中的应用方法;②学习,体现了PLC在工业自动化控制中的高效全自动洗衣机控制系统的性与可靠性。;软硬件设计流程 适合人群:电气;③实践工程、自动化及相关MCGS组态软件与PLC的专业的本科生、初级通信与联调工程技术人员以及从事;④完成PLC控制系统开发毕业设计或工业的学习者;具备控制类项目开发参考一定PLC基础知识。; 阅读和梯形图建议:建议结合三菱编程能力的人员GX Works2仿真更为适宜。; 使用场景及目标:①应用于环境与MCGS组态平台进行程序高校毕业设计或调试与运行验证课程项目,帮助学生掌握PLC控制系统的设计,重点关注I/O分配逻辑、梯形图与实现方法;②为工业自动化领域互锁机制及循环控制结构的设计中类似家电控制系统的开发提供参考方案;③思路,深入理解PL通过实际案例理解C在实际工程项目PLC在电机中的应用全过程。控制、时间循环、互锁保护、手动干预等方面的应用逻辑。; 阅读建议:建议结合三菱GX Works2编程软件和MCGS组态软件同步实践,重点理解梯形图程序中各环节的时序逻辑与互锁机制,关注I/O分配与硬件接线的对应关系,并尝试在仿真环境中调试程序以加深对全自动洗衣机控制流程的理解。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值