zoukankan      html  css  js  c++  java
  • a题解

    (a)题解

    题目描述

    首先考虑(60)分暴力,可以对每一个字母用前缀和维护一下。

    然后我们可以得到

    [ans=max(sum[a][r]-sum[a][l-1])-min(sum[b][r]-sum[b][l-1]) ]

    我们设(a)字符为(max)(b)设为(min)

    [ans=(sum[a][r]-sum[a][l-1])-(sum[b][r]-sum[b][l-1]) ]

    化简得

    [ans=(sum[a][r]-sum[a][l-1])-(sum[b][r]-sum[b][l-1]) ]

    [ans=sum[a][r]-sum[b][r]-(sum[a][l-1]-sum[b][l-1]) ]

    对于字符的枚举,我们发现不用(26^2)去枚举,因为每次加字符只有当前的字符数量变化,所以我们只需要枚举新加的字符就可以了。

    我们发现对于(sum[a][l-1]-sum[b][l-1]),我们并不关心(l-1)是什么,我们只关心它们的差值的最小值,所以我们用(minn[a][b])表示(a)(b)差值的最小值。

    对于(sum[a][r])(sum[b][r]),因为(r)是当前枚举的,所以我们直接用(sum[a])(sum[b])来代替。

    所以

    [ans=max(ans,sum[a]-sum[b]-minn[a][b]) ]

    因为区间内(a)或者(b)都不能等于(0),所以我们记录一个(pos[a][b])表示(minnn[a][b])出现的位置,记录一个(last[j])表示(j)这个字符最后出现的位置,如果(pos[a][b]==last[b])证明这段区间里没有(b),所以我们要新加在(last[b])位置的这个(b),也就是更新时答案减一。

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e6+100,M=30;
    char s[N];
    int sum[M],last[M],pos[M][M],minn[M][M];
    int n,ans=0;
    int main()
    {
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
        scanf("%d",&n);
        scanf("%s",s+1);
        for (int i=1;i<=n;i++)
        {
            int now=s[i]-'a'+1;
            last[now]=i;
            sum[now]++;
            for (int j=1;j<=26;j++)
            {
                int tmp;
                if (sum[j]&&now!=j)
                {
                    tmp=sum[now]-sum[j]-minn[now][j];
                    if (pos[now][j]==last[j]) tmp--;
                    ans=max(ans,tmp);
                    tmp=sum[j]-sum[now]-minn[j][now];
                    if (pos[j][now]==last[j]) tmp--;
                    ans=max(ans,tmp);
                }
            }
            for (int j=1;j<=26;j++)
            {
                if (sum[now]-sum[j]<minn[now][j])
                {
                    minn[now][j]=sum[now]-sum[j];
                    pos[now][j]=i;
                }
                if (sum[j]-sum[now]<minn[j][now])
                {
                    minn[j][now]=sum[j]-sum[now];
                    pos[j][now]=i;
                }
            }
        }
        printf("%d
    ",ans);
        getchar();getchar();
        return 0;
    }
    
  • 相关阅读:
    C#控件随窗体大小改变而改变
    Java泛型
    php的stristr()函数,查找字符
    java设计模式之桥梁模式(Bridge)
    怎样从本地删除git远程仓库里面的文件
    VS code 修改主题设置代码对其齐线
    vue+webpack安装sass过程中遇到权限不够,直接删除node_modus文件夹重新安装,node_modus先取得管理员权限才能删
    转:git合并冲突解决方法
    git命令行解决冲突文件步骤
    dos常用命令
  • 原文地址:https://www.cnblogs.com/last-diary/p/11479150.html
Copyright © 2011-2022 走看看