[CF822E]Liar

题目大意

给定两个字符串S和T。你可以把S分成若干段,从左到右从1开始编号。现在要从你分出来的段中取出不超过x段,按编号从小到大依次拼接成字符串T。问是否有可行解。

1≤|T|≤|S|≤100000 x≤30

分析

考虑DP。设f[i][j]表示用了S的前i个字符,取出了j段,最大能得到T的前多少个字符。
转移分两种情况:
1. f[i][j]—>f[i+1][j] 表示字符i+1单独成段且没被选
2. f[i][j]—>f[i+lcp][j+1] 其中lcp是S的后缀i+1和T的后缀f[i][j]+1的lcp。这里表示这一段lcp被选中。很显然取lcp的长度比取小于lcp的长度要更优。

最终复杂度就取决于如何求lcp了。设字符串总长为N,如果用后缀数组加rmq可以做到O(NlogN)预处理+O(1)查询。不过时限较大,可以用hash+二分,时间复杂度为O(NxlogN)

#include <cstdio>
#include <cstring>
#include <algorithm>

#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))

using namespace std;

const int N=100005,M=31,mo[2]={998244353,1004535809},INF=1e9;

typedef long long LL;

int n,m,K,h1[2][N],h2[2][N],p[2][N],f[N][M];

char s[N],t[N];

bool Same(int x,int y,int l)
{
    for (int i=0;i<2;i++)
    {
        if ((mo[i]+(h1[i][x+l-1]-(LL)h1[i][x-1]*p[i][l])%mo[i])%mo[i]!=(mo[i]+(h2[i][y+l-1]-(LL)h2[i][y-1]*p[i][l])%mo[i])%mo[i]) return 0;
    }
    return 1;
}

int getlcp(int x,int y)
{
    int l,r,mid;
    for (l=0,r=min(n-x+1,m-y+1),mid=r>>1;l<r;mid=l+r>>1)
        if (!Same(x,y,mid)) r=mid;else l=mid+1;
    if (!Same(x,y,l)) l--;
    return l;
}

int main()
{
    scanf("%d%s%d%s%d",&n,s+1,&m,t+1,&K);
    for (int j=0;j<2;j++)
    {
        p[j][0]=1;
        for (int i=1;i<N;i++) p[j][i]=(LL)p[j][i-1]*26%mo[j];
        for (int i=1;i<=n;i++) h1[j][i]=((LL)h1[j][i-1]*26+s[i]-'a')%mo[j];
        for (int i=1;i<=m;i++) h2[j][i]=((LL)h2[j][i-1]*26+t[i]-'a')%mo[j];
    }
    f[0][0]=0;
    for (int i=0;i<n;i++)
    {
        for (int j=0;j<K;j++) if (f[i][j]<m)
        {
            int k=f[i][j],lcp=getlcp(i+1,k+1);
            f[i+1][j]=max(f[i+1][j],k);
            if (lcp>0) f[i+lcp][j+1]=max(f[i+lcp][j+1],k+lcp);
        }
    }
    for (int i=1;i<=n;i++) for (int j=1;j<=K;j++) if (f[i][j]==m)
    {
        printf("YES\n"); return 0;
    }
    printf("NO\n");
    return 0;
}
<think>嗯,用户这次询问的是Liar-IMU算法,但根据提供的引用内容,我发现存在术语混淆——引用[1]中明确出现了"Liar/odometry"的拼写错误(应为Lidar),而用户提问时也延续了这个错误拼写。这需要先澄清术语以避免概念混淆。 用户提供的三则引用中,引用[1]描述了IMU预积分模块的独立性,引用[2]是课程广告,引用[3]讨论LOAM算法。核心有效信息集中在引用[1]和[3]:前者说明IMU预积分处理流程独立,后者详述激光SLAM的经典框架LOAM。用户实际想了解的应该是Lidar-IMU融合算法,典型代表如LIO-SAM(引用[2]末尾提及)。 考虑到用户研究背景(引用[3]显示其在阅读SLAM源码),回复需要突出: 1. 算法原理层面:解释紧耦合方案中IMU预积分如何修正点云畸变并提供初始位姿 2. 工程实现层面:结合引用[1]强调模块化设计(如imuPreintegration.cpp的独立性) 3. 典型应用:引用[2][3]提到的无人驾驶、机械臂抓取等场景 特别要注意纠正术语错误,但需用温和方式说明(比如标注"可能为笔误")。由于用户提到"看代码似懂非懂",可建议其关注LIO-SAM的注释版本(引用[2]线索),这对源码理解更友好。 用户可能还需要扩展资料,因此问题设计应包含:具体开源项目(如LIO-SAM)、数学工具(预积分方程)、与其他方案(如VIO)对比。这些都能帮助用户建立系统认知。 </think> 根据您提供的引用内容和术语分析,"Liar IMU" 可能是 **Lidar-IMU**(激光雷达-惯性测量单元)的拼写误差。这是一种多传感器融合的SLAM(同步定位与建图)技术,结合激光雷达的高精度测距能力和IMU的高频运动估计。以下是核心技术解析: --- ### **Lidar-IMU融合算法原理** 1. **传感器互补性** - **激光雷达(Lidar)**:提供高精度环境点云,但低频(通常10-20Hz)且运动畸变敏感。 - **IMU**:高频测量(100-1000Hz)载体角速度和线性加速度,但存在零偏漂移。 *两者互补可提升SLAM的鲁棒性和精度*[^1]。 2. **紧耦合融合框架** - **前端**:IMU预积分技术(如`imuPreintegration.cpp`模块)实时估计帧间运动,补偿Lidar点云畸变[^1]。 - **后端**:将IMU预积分结果与Lidar点云匹配共同构建优化问题(如因子图优化),联合优化位姿和地图[^3]。 $$ \min_{T} \left( \underbrace{\| f_{\text{Lidar}}(T) \|^2_{\Sigma_L}}_{\text{Lidar残差}} + \underbrace{\| f_{\text{IMU}}(T) \|^2_{\Sigma_I}}_{\text{IMU残差}} \right) $$ *其中 $T$ 为位姿变换,$\Sigma$ 为协方差矩阵* 3. **关键技术模块** - **IMU预积分**:避免重复积分,将IMU数据转换为相对运动约束。 - **点云配准**:使用ICP或NDT匹配相邻帧点云。 - **闭环检测**:基于历史点云识别回环,修正累积误差。 --- ### **典型算法与应用场景** | **算法** | **特点** | **应用领域** | |----------------|---------------------------------------|---------------------------| | **LIO-SAM** | 紧耦合+因子图优化,支持GPS融合 | 自动驾驶、无人机勘探[^2] | | **LIO-Mapping**| 基于IKFoM的迭代卡尔曼滤波 | 地下矿井、无GPS环境 | | **FAST-LIO** | 高计算效率,适用于嵌入式平台 | 移动机器人、AGV小车 | > 📌 **应用场景**: > - **自动驾驶**:城市道路高精度定位(如LIO-SAM)[^2] > - **三维重建**:手持设备扫描建筑(结合3DGS技术) > - **机械臂抓取**:实时感知作业环境点云[^2] --- ### **优势与挑战** - **优势** - **鲁棒性**:IMU辅助解决Lidar快速运动导致的失效问题 - **实时性**:IMU提供高频位姿预测,减少优化计算量 - **挑战** - **标定精度**:Lidar-IMU外参标定误差显著影响结果 - **动态物体**:移动物体导致点云匹配失真 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值