• 【BZOJ】3790 神奇项链


    【算法】(manacher+贪心)||(manacher+DP+树状数组/线段树)

    【题解】

    manacher求回文串,后得到线段,做一点计算映射回原串线段。

    然后问题转化为可重叠区间线段覆盖问题,可以贪心解决。

    排序左端点,同一左端点取最长段,然后在此段中找到右端点最靠右的线段,线性更新并累加。

    DP的话:f[i]表示刚好覆盖1...i的最少线段(即最后一条线段右端点在i上),则按顺序枚举线段a[i],

    f[a[i].r]=min(f[j])+1 , j=(a[i].l,a[i].l+1,...,a[i].r-1),显然a[n]为答案。

    于是可以用树状数组或线段树来在线维护min(f[j])。

    两者复杂度皆为o(n log n)。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn=200010;
    int n,p[maxn];
    char s[maxn],ss[maxn];
    struct cyc{int l,r;}a[maxn];
    bool cmp(cyc a,cyc b)
    {return a.l<b.l||(a.l==b.l&&a.r>b.r);}
    void manacher()
    {
        memset(p,0,4*(n+1));
        int id=0,mx=0;
        for(int i=1;i<=n;i++)
         {
             if(mx>i)
              p[i]=min(p[id*2-1],mx-i+1);
             else p[i]=1;
             while(s[i+p[i]]==s[i-p[i]])p[i]++;
             if(i+p[i]-1>mx)
              {
                  mx=i+p[i]-1;
                  id=i;
              }
    //         printf("p[%d]=%d
    ",i,p[i]);
             if(i%2)a[i].l=i/2-p[i]/2+1,a[i].r=i/2+p[i]/2;
              else a[i].l=i/2-p[i]/2+1,a[i].r=i/2+p[i]/2-1;
             if(a[i].l>a[i].r)a[i].l=a[i].r=1;
         }
    //    for(int i=1;i<=n;i++)printf("%d %d
    ",a[i].l,a[i].r);
    }
    int main()
    {
        while(scanf("%s",ss+1)==1)
         {
             int tot=strlen(ss+1);
             n=1;s[0]='$';s[1]='#';
             for(int i=1;i<=tot;i++)s[++n]=ss[i],s[++n]='#';
             manacher();
             sort(a+1,a+n+1,cmp);
             int right=a[1].r,ans=1,mx=0;
    //         for(int i=1;i<=n;i++)printf("a[%d]l=%d r=%d
    ",i,a[i].l,a[i].r);
             for(int i=2;i<=n;i++)
             if(a[i].l!=a[i-1].l)
               {
                   if(a[i].l>right+1)ans++,right=mx;
                   mx=max(mx,a[i].r);
               }
             if(right<tot)ans++;
             printf("%d
    ",ans-1);
         }
        return 0;
    }
    贪心
  • 相关阅读:
    Vue $emit()不触发方法的原因
    java 定时任务之一 @Scheduled注解(第一种方法)
    Dubbo的使用及原理浅析.
    Android App 安全的HTTPS 通信
    详解intellij idea搭建SSM框架(spring+maven+mybatis+mysql+junit)
    IDEA 2018集成MyBatis Generator 插件 详解
    自建证书配置HTTPS服务器
    Jsoup(一)Jsoup详解(官方)
    Android使用最小宽度限定符时最小宽度的计算
    可显示行号的log工具
  • 原文地址:https://www.cnblogs.com/onioncyc/p/6670678.html
Copyright © 2020-2023  润新知