noip模拟赛 a

分析:其实就是要求sum[a][r] - sum[a][l - 1] - (sum[b][r] - sum[b][l - 1])最大,变形一下,可以得到sum[a][r] - sum[b][r] - (sum[a][l - 1] - sum[b][l - 1]),我们可以枚举位置r和b,a就是当前位置的字符,那么后面的(sum[a][l - 1] - sum[b][l - 1])我们可以在前面用一个数组记录一下最小值,这样扫一遍就能出答案.不过有一种特殊情况是sum[a][l - 1] - sum[b][l - 1]最小的位置可能和上一次b出现的位置冲突,因为一个位置上不可能出现2个字母,所以答案-1就可以了.

      写出式子来要等价变形!把结构相同的放在一类,然后思考如何优化!

 

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

using namespace std;

int n, last[1000010], f[30][30], sum[30], ans;
int pos[30][30];
char s[1000010];

int main()
{
    scanf("%d", &n);
    scanf("%s", s + 1);
    memset(f, 0x3f, sizeof(f));
    for (int i = 1; i <= n; i++)
    {
        int p = s[i] - 'a';
        sum[p]++;
        last[p] = i;
        for (int j = 0; j < 26; j++)
            if (p != j && sum[j])
            ans = max(ans, max(sum[p] - sum[j] - f[p][j] - (last[j] == pos[p][j] ? 1 : 0), sum[j] - sum[p] - f[j][p] - (last[j] == pos[j][p] ? 1 : 0)));
        for (int j = 0; j < 26; j++)
        {
            if (sum[p] - sum[j] < f[p][j])
            {
                f[p][j] = sum[p] - sum[j];
                pos[p][j] = i;
            }
            if (sum[j] - sum[p] < f[j][p])
            {
                f[j][p] = sum[j] - sum[p];
                pos[j][p] = i;
            } 
        }
    }
    printf("%d\n", ans);

    return 0;
}

 

posted @ 2017-10-15 22:03  zbtrs  阅读(178)  评论(0编辑  收藏  举报