zoukankan      html  css  js  c++  java
  • 中南多校对抗赛 第三场 B

    B:Arithmetic Progressions

    题意:

    给你一个长度为n的序列,问你这个序列中长度最长的等差数列长度为多少

    题解:

    方法一:将数组从小到大排序,n方扫,枚举出公差d,然后二分找有多少个满足等差序列的值即可,emmm虽然说不知道为什么这种最差复杂度为n^3*logn的暴力能过,可能是csuoj太快了吧。

    代码:

    #include <bits/stdc++.h>
    #define eps 1e-8
    #define INF 0x3f3f3f3f
    #define PI acos(-1)
    #define lson l,mid,rt<<1
    #define rson mid+1,r,(rt<<1)+1#define CLR(x,y) memset((x),y,sizeof(x))
    #define fuck(x) cerr << #x << "=" << x << endl
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const int seed = 131;
    const int maxn = 1e5 + 5;
    const int mod = 1e9 + 7;
    int n;
    ll a[maxn];
    int main() {
        scanf("%d", &n);
        for (int i = 1; i <= n; i++) scanf("%lld", &a[i]);
        sort(a + 1, a + 1 + n);
        int ans = 2;
        for (int i = 1; i <= n; i++) {
            for (int j = i + 1; j <= n; j++) {
                ll d = a[j] - a[i];
                ll nxt = d + a[j];
                int num = 2;
                int k = j;
                while (1) {
                    k = lower_bound(a + k + 1, a + 1 + n, nxt) - a;
                    if (a[k] != nxt) break;
                    nxt += d;
                    num++;
                }
                ans = max(ans, num);
            }
        }
        printf("%d
    ", ans);
        return 0;
    }
    ​
    View Code

    方法二:由于不会暴力,于是就开始了dp

    定义状态:

    因为我们肯定要保存一个公差作为状态量,但是直接枚举又不现实。所以我们巧妙的设计出了这个状态,使得我们的公差就被表示了因此我们的转移就应该是在三个数中转移。即,,但是直接枚举也是不现实的根据等差数列的性质,若构成等差序列,那么所以转移就是每次转移更新答案即可我们枚举和,那么可以用双指针给处理出来从而让复杂度将为的级别

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 5005;
    const int INF = 0x3f3f3f3f;
    int dp[maxn][maxn];
    int a[maxn];
    int main() {
        int n;
        scanf("%d", &n);
        for(int i = 1; i <= n; i++) {
            scanf("%d", &a[i]);
        }
        sort(a + 1, a + n + 1);
        int ans = 2;
        for(int i = 1; i < n; i++) {
            int j = i - 1;
            for(int k = i + 1; k <= n && j; k++) {
                while(j && a[j] + a[k] > a[i] + a[i]) {
                    j--;
                }
                if(j && a[j] + a[k] == a[i] + a[i]) {
                    if(dp[i][j] == 0) {
                        dp[k][i] = 3;
                    } else {
                        dp[k][i] = dp[i][j] + 1;
                    }
                    ans = max(dp[k][i], ans);
                }
            }
        }
        cout << ans << endl;
    }
    View Code

     

    每一个不曾刷题的日子 都是对生命的辜负 从弱小到强大,需要一段时间的沉淀,就是现在了 ~buerdepepeqi
  • 相关阅读:
    8款最新CSS3表单 环形表单很酷
    8款给力HTML5/CSS3应用插件 可爱的HTML5笑脸
    分享10款效果惊艳的HTML5图片特效
    9款极具创意的HTML5/CSS3进度条动画
    分享9款最新超酷HTML5/CSS3应用插件
    7款HTML5精美应用教程 让你立即爱上HTML5
    (转)整理 node-sass 安装失败的原因及解决办法
    分析Vue框架源码心得
    Vue中的render函数随笔
    微信小程序商业级实战
  • 原文地址:https://www.cnblogs.com/buerdepepeqi/p/10630194.html
Copyright © 2011-2022 走看看