• ZJNU 2220


    找最长的等差数列长度

    数据范围是 n<=2000,a[i]<=2000

    容易想到的是枚举等差数列前两项,得到差值后向后查找

    a数组存数值,b数组存某个数出现的个数(也可判断是否出现过)

    这是个O(n^3)级别的想法,所以必须在此基础上继续优化

    首先排除公差为0的情况,即找出相同的数出现最多次的次数

    然后将数列排序后去重,使得剩下的元素两两不相等

    这时候就可以开始枚举 i 和 j 两项了

    但是从最坏情况考虑,2000项互不相同的测试点时间复杂度仍然是O(n^3),去重没法对这种情况进行优化

    所以可以从剪枝入手,在每一次搜索前将可能得到的最大的答案跟目前的答案进行比较

    即先把a数组最大的元素存在变量mx中,枚举出 a[i] 后根据 (mx-a[i])/d 来计算可能得到的最大的答案

    如果这个值小于等于目前的答案ans,说明这个分支无法对答案做出贡献,就可以直接跳出整个 j 循环

    #include<bits/stdc++.h>
    using namespace std;
    int a[2050],b[4050];
    void solve(){
        int n,i,j,k,d,ans=1,mx=0;
        memset(b,0,sizeof b);
        cin>>n;
        for(i=1;i<=n;i++){
            cin>>a[i];
            ans=max(ans,++b[a[i]]);
            mx=max(mx,a[i]);
        }
        sort(a+1,a+1+n);
        n=unique(a+1,a+1+n)-a-1;
        for(i=1;i<n;i++)
            for(j=i+1;j<=n;j++){
                d=a[j]-a[i];
                if((mx-a[i])/d<=ans)
                    break;
                for(k=a[j]+d;b[k];k+=d);
                ans=max(ans,(k-a[i])/d);
            }
        cout<<ans<<'
    ';
    }
    int main(){
        ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
        int T;cin>>T;for(int t=1;t<=T;t++)
            solve();
        return 0;
    }
  • 相关阅读:
    Ehcache(2.9.x)
    Ehcache(2.9.x)
    Ehcache(2.9.x)
    Ehcache(2.9.x)
    Ehcache(2.9.x)
    Ehcache(2.9.x)
    Ehcache(2.9.x)
    网站静态化处理—反向代理(10)
    网站静态化处理—满足静态化的前后端分离(9)
    网站静态化处理—前后端分离—下(8)
  • 原文地址:https://www.cnblogs.com/stelayuri/p/12409846.html
Copyright © 2020-2023  润新知