zoukankan      html  css  js  c++  java
  • codeforces-1335-E Three Blocks Palindrome

    codeforces-1335-E Three Blocks Palindrome

    传送门:

    easy:https://codeforces.com/contest/1335/problem/E1

    hard:https://codeforces.com/contest/1335/problem/E2

    题意:

    定义 three blocks palindrome 为 aaaaabbbaaaaa,其中两边的a必须个数相等 而且序列中只存在两种元素

    1 1 1 2 3 2 1 1 1 是不可以的 1 1 1 2 1 2 1 1 1 也是不可以的

    给你一段序列 找到最长的 three blocks palindrome 子序列(可以不连续)

    这个题 是个纯暴力

    说一下思路

     用一个前缀和 sum[i][j] 记下来在 i 这个位置有多少 j    1<=i<=n<=2e5      1<= j = a[i]<=200

    把a[i]出现过的位置记下来,后面有用,我是用的vector

    然后遍历1-200 内的每一个数作为上面的a,也就是在两边的部分 更新最大值

    找到了 a ,在每两个 a 之间找到(这两个a中间夹着的重复的数的最大值+min(1到左面的a的位置有多少a,右面的a的位置到结尾有多少a )*2 )的最大值

    不理解??

    5 5 5 5 5 5 5 1 1 2 3 2 1 1 1  a=1时最优的选择是什么呢 1 1 2 2 1 1 因为要保证两边a的距离相等所以取小 因为a=1指定没有a=5长,所以每次取最大

    这个在每两个a之间找,暴力的话可以套俩循环,easy是指定能过的,hard没有试,要做一下优化

    想一下 1 2 3 4 5 6 7 8 这些个位置,如果是找1 8 max(之间中间夹着的重复的数)一定比1 5之间的 max(之间中间夹着的重复的数) 要多,如果右面是位置5的情况比较大,那一定是1往右移了

    所以我们duck不必套俩循环,一左一右往中间缩就好了

     行了,去模拟吧

    还有 sum 不用memset 初始化会tle 他是每次覆盖上去的

    j<ve[i].size()/2 不能写成j*2<ve[i].size()        j=1,ve[i].size()=3会错

    maxx初值赋成1 因为最小的长度就是它本身也是1,而且这种情况根本无法更新最大值,赋成-1或者0你就凉了

    easy版代码就不粘了,比这个还要暴力呢

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    const int mod=1e9+7;
    const int inf=0x3f3f3f3f;
    int a[200009];
    int sum[200009][209];//i j 在i处有多少j
    vector<int>ve[300];
    int main()
    {
        int _;
        for(scanf("%d",&_); _; _--)
        {
            for(int i=0; i<202; i++) ve[i].clear();
            int n;
            scanf("%d",&n);
            for(int i=1; i<=n; i++)
            {
                scanf("%d",&a[i]);
                ve[a[i]].push_back(i);
                for(int j=1; j<=200; j++)
                {
                    if(j==a[i]) sum[i][j]=sum[i-1][j]+1;
                    else sum[i][j]=sum[i-1][j];
                }
            }
            int maxx=1;
            for(int i=1; i<=200; i++)
            {
                for(int j=0; j<ve[i].size()/2; j++)
                {
                    int mx=0;
                    int k=ve[i].size()-j-1;
                    for(int k_=1; k_<=200; k_++)
                    {
                        int sm=sum[ve[i][k]-1][k_]-sum[ve[i][j]][k_];
                        mx=max(mx,sm);
                    }
                    maxx=max(mx+2*(j+1),maxx);
                }
            }
            printf("%d
    ",maxx);
        }
        return 0;
    }
  • 相关阅读:
    手把手教你接入微信支付
    Java中的深浅拷贝问题,你清楚吗?
    DeimosC2 源码阅读
    一行命令删除空的docker images
    docker build出现交互式时区设置解决
    Amass项目源码阅读(整体架构)
    Prometheus时序数据库-磁盘中的存储结构
    Prometheus时序数据库-内存中的存储结构
    解Bug之路-ZooKeeper集群拒绝服务
    日常Bug排查-Nginx重复请求?
  • 原文地址:https://www.cnblogs.com/YangKun-/p/12701389.html
Copyright © 2011-2022 走看看