zoukankan      html  css  js  c++  java
  • [bzoj2213][Poi2011]Difference_动态规划

    Difference bzoj-2213 Poi-2011

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

    注释:$1le nle 10^6$。


    想法:“在线”的dp题。

    状态:$dp[i][j]$表示在当前位置,字母$i$与字母$j$之间的最大差,$dp2[i][j]$表示出现次数的差。

    这样的话就可以拿来更新答案了。

    至于复杂度的的话,因为每次从$i$更新到$i+1$只会更改52个值,所以复杂度是$O(n)$的。

    最后,附上丑陋的代码... ...

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define K 50
    using namespace std;
    int sum[K],f[K][K],g[K][K],c[K][K],h[K][K],d[K][K],ans;
    char str[1000010];
    void update(int a , int b)
    {
        if(c[a][b] < sum[b]) ans = max(ans , f[a][b] - g[a][b]);
        else if(d[a][b] < sum[b]) ans = max(ans , f[a][b] - h[a][b]);
        if(f[a][b] < g[a][b])
        {
            if(c[a][b] < sum[b]) h[a][b] = g[a][b] , d[a][b] = c[a][b];
            g[a][b] = f[a][b] , c[a][b] = sum[b];
        }
        else if(c[a][b] < sum[b] && f[a][b] < h[a][b]) h[a][b] = f[a][b] , d[a][b] = sum[b];
    }
    int main()
    {
        int n,t;
        scanf("%d%s" , &n , str + 1);
        for(int i=1;i<=n;i++)
        {
            t=str[i]-'a'; sum[t]++;
            for(int j=0;j<K;j++)
                if(t != j) f[t][j]++,update(t,j),f[j][t]--,update(j,t);
        }
        printf("%d
    ",ans);
        return 0;
    }
    

     小结:挺好的题(好像是lzh的考试题)。

  • 相关阅读:
    Webservice详解
    Spring IOC/DI和AOP原理
    MySQL 使用JOIN优化子查询
    MySQL 更新语句技巧
    MySQL插入语句解析
    MySQL用户无法登陆问题
    MySQL基础学习(二) 常用SQL命令
    Servlet/JSP-08 EL表达式
    插值和空间分析(一)_探索性数据分析(R语言)
    爱重启的windows,伤不起
  • 原文地址:https://www.cnblogs.com/ShuraK/p/9537221.html
Copyright © 2011-2022 走看看