zoukankan      html  css  js  c++  java
  • CF1335E2-Three Blocks Palindrome (hard version) (二分+双指针)

    题目大意:

    题意就是告诉你一个数n,然后给你n个数,每个数满足1<=a[i]<=200,让你求最大的子序列,子序列由x个a和y个b和x个a构成。

    链接:https://codeforces.com/contest/1335/problem/E2

    思路:

    我们先用一个vector v记录1-200中每个数出现的位置,这里以1为例,v[1]中记录的是1这个数出现的所有位置,

    然后我们用两个指针l(指向v[1]中的第一个数)和r(指向v[1]中的最后一个数),此时x=1,我们不难发现,1-200中的每个数,

    只要出现在v[1][l]和v[1][r]之间均能满足所给条件,然后l++,r--,x++(x代表左边有x个1,右边有x个1),然后继续寻找,

    不断的取最大值即可。复杂度为n*n*log(n),呸,转头一想好像不是这个复杂度(因为还要算上双指针移动,菜逼不知道咋算,

    当时就想着试试感觉能过然后就过了),因为a[i]的最大值为200(即n的上限为200),所以能跑过去,不过好像是刚刚水过去。

    可能我表述的有些混乱,看了代码应该可以稍微清晰一点。

    代码:

    #include <bits/stdc++.h>
    #define Pair pair<int,int>
    using namespace std;
    typedef long long ll;
    const int MAXN=5e5+5;
    const int INF=1e9;
    int a[MAXN];
    vector<int>v[300];
    int main()
    {
        ios::sync_with_stdio(false);cin.tie(0);
        int t;cin>>t;
        while(t--)
        {
            int n;
            cin>>n;
            for(int i=1; i<=200; i++)
                v[i].clear();
            for(int i=1; i<=n; i++)
            {
                cin>>a[i];
                v[a[i]].push_back(i);   //记录每个a[i]出现的位置
            }
            int max_=1;
            for(int i=1; i<=200; i++)
            {
                int ans=0;
                int l=0,r=v[i].size()-1;
                while(l<r)
                {
                    //printf("%d %d %d
    ",i,l,r);
                    int item1=v[i][l],item2=v[i][r];
                    //printf("%d %d
    ",item1,item2);
                    ans+=2;     //因为子序列左边添了一个,右边添了一个,所以此时子序列的长度加2
                    for(int j=1; j<=200; j++)
                    {
                        if(v[j].empty())
                            continue;
                        if(j==i)
                        {
                            max_=max(max_,(int)v[i].size());
                            continue;
                        }
                        int index1=upper_bound(v[j].begin(),v[j].end(),item1)-v[j].begin();
                        int index2=upper_bound(v[j].begin(),v[j].end(),item2)-v[j].begin()-1;
                        //index2-index1+1为中间的数的个数,ans+index2-index1+1即为子序列的大小
                        max_=max(max_,ans+index2-index1+1);
                    }
                    l++;r--;
                }
            }
            printf("%d
    ",max_);
        }
    
    
        return 0;
    }
  • 相关阅读:
    NFS
    Linux ISO镜像挂载
    Python3.6 提示 ModuleNotFoundError: No module named '_ssl' 模块问题
    mysql 5.7 ERROR 1054(42S22) Unknown column 'password' in ‘field list’ 报错
    Redis + keepalived 高可用行配置检测脚本
    Linux 文件大小查找排序
    查看 Centos 7 的MAC 地址
    Discuz 论坛 (LAMP环境)
    SVN
    systemctl
  • 原文地址:https://www.cnblogs.com/ljxdtc666/p/12700077.html
Copyright © 2011-2022 走看看