zoukankan      html  css  js  c++  java
  • BZOJ2213[Poi2011]Difference——DP

    题目描述

    A word consisting of lower-case letters of the English alphabet ('a'-'z') is given. We would like to choose a non-empty contiguous (i.e. one-piece) fragment of the word so as to maximise the difference in the number of occurrences of the most and the least frequent letter in the fragment. We are assuming that the least frequent letter has to occur at least once in the resulting fragment. In particular, should the fragment contain occurrences of only one letter, then the most and the least frequent letter in it coincide.

    已知一个长度为n的由小写字母组成的字符串,求其中连续的一段,满足该段中出现最多的字母出现的个数减去该段中出现最少的字母出现的个数最大。求这个个数。

    输入

    The first line of the standard input holds one integer (1<=N<=1000000) that denotes the length of the word. The second line holds a word consisting of lower-case letters of the English alphabet.

    第一行,n
    第二行,该字符串
    1<=n<=1000000

    输出

    The first and only line of the standard output is to hold a single integer, equal to the maximum difference in the number of occurrences of the most and the least frequent letter that is attained in some non-empty contiguous fragment of the input word.

    一行,表示结果

    样例输入

    10
    aabbaaabab

    样例输出

    3
    Explanation of the example: The fragment that attains the difference of 3 in the number of occurrences of a and b is aaaba.
     
    一道很好的思维题。
    假设最后答案的那一段中最多的是a,最少的是b,那么答案就是(ra-la)-(rb-lb),其中l,r代表序列端点处的前缀和,变换之后也就是(ra-rb)+(lb-la),也就是求端点位置前缀和之差。我们设f[i][j]表示当前位置之前的某一位置i字符个数减j字符个数的最大值,g[i][j]表示当前位置i字符个数减j字符个数的值。因为每多一个位置只有一种字符的个数被改变,如果对答案有影响,那么当前位字符一定是答案中的那个最大值或者最小值。枚举其他25个字符,考虑当前位为最大值枚举字符为最小值或当前位为最小值枚举字符为最大值时对答案的影响来更新答案即可。时间复杂度O(26n)。
    #include<map>
    #include<set>
    #include<queue>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    char a[1000000];
    int s[30];
    int n;
    int ans;
    int f[30][30];
    int g[30][30];
    int main()
    {
        scanf("%d",&n);
        scanf("%s",a+1);
        memset(f,0xef,sizeof(f));
        for(int i=1;i<=n;i++)
        {
            int x=a[i]-'a'+1;
            s[x]++;
            for(int j=1;j<=26;j++)
            {
                if(x!=j)
                {
                    f[x][j]=max(f[x][j],g[x][j]);
                    g[x][j]=s[x]-s[j];
                    ans=max(ans,max(s[x]-s[j]+f[j][x],s[j]-s[x]+f[x][j]));
                }
            }
        }
        printf("%d",ans);
    }
  • 相关阅读:
    Java并发包中Lock的实现原理
    多线程---再次认识volatile,Synchronize,lock
    共享锁(S锁)和排它锁(X锁)
    Java 7中的TransferQueue 以及 SynchronousQueue
    精巧好用的DelayQueue
    非阻塞同步算法与CAS(Compare and Swap)无锁算法
    彻底理解线索二叉树
    使用import取代require
    子页面iframe跨域执行父页面定义的JS方法
    利用js实现 禁用浏览器后退
  • 原文地址:https://www.cnblogs.com/Khada-Jhin/p/9590011.html
Copyright © 2011-2022 走看看