• 中南多校对抗赛 第三场 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
  • 相关阅读:
    UVa 1643 Angle and Squares
    UVa 1210 (高效算法设计) Sum of Consecutive Prime Numbers
    UVa 1213 (01背包变形) Sum of Different Primes
    UVa 1644 (筛素数 + 二分) Prime Gap
    UVa 10048 (Floyd变形) Audiophobia
    UVa 247 (传递闭包) Calling Circles
    UVa 808 (建坐标系、找规律) Bee Breeding
    UVa 1151 (枚举 + MST) Buy or Build
    UVa 1395 (最小生成树) Slim Span
    UVa 11040 (水题) Add bricks in the wall
  • 原文地址:https://www.cnblogs.com/buerdepepeqi/p/10630194.html
Copyright © 2020-2023  润新知