E - Two Platforms

题意不再赘述,思路可以用前缀后缀最大值来写,用一个 l [ i ] l[i] l[i],代表前缀为 i i i最多取多少球, r [ i ] r[i] r[i]代表后缀为 i i i最多为取多少球,枚举 l [ i ] + r [ i + 1 ] l[i]+r[i+1] l[i]+r[i+1]的最大值即可,这样已经避免区间覆盖。

参考代码

/*
 * @Author: vain
 * @Date: 2020
 * @LastEditTime: 2020-10-01 15:29:52
 * @LastEditors: sueRimn
 * @Description: 学不会 dp 的 fw
 * @FilePath: \main\demo.cpp
 */
//#include <bits/stdc++.h>
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <ctime>
#include <cstring>
#include <cstdlib>
#include <math.h>
#include <bitset>
using namespace std;
typedef long long ll;
#define ll long long
//typedef unsigned long long uint;
const int N = 5000 + 20;
const int maxn = 2e5 + 20;
int a[maxn], vis[maxn];
// typedef pair<int, int> p;
// priority_queue<p, vector<p>, greater<p>> m;
//int sum[maxn];
//ll max(ll a, ll b) { return a > b ? a : b; }
int min(int a, int b) {
    
     return a < b ? a : b; }
int gcd(int a, int b) {
    
     return b ? gcd(b, a % b) : a; }
int lcm(int a, int b) {
    
     return a * b / gcd(a, b); }
void swap(int &x, int &y) {
    
     x ^= y, y ^= x, x ^= y; }
int lowbit(int x) {
    
     return (x) & (-x); }
ll ksm(ll a, ll b)
{
    
    
    ll res = 1;
    for (; b;)
    {
    
    
        if (b & 1)
            res *= a;
        b >>= 1, a = a * a;
    }
    return res;
}
int x[maxn], l[maxn], r[maxn];
int main()
{
    
    
    int t, n, m, k;
    scanf("%d", &t);
    while (t--)
    {
    
    
        scanf("%d %d", &n, &k);
        for (int i = 1; i <= n; i++)
            scanf("%d", &x[i]), l[i] = r[i] = 0;
        for (int i = 1; i <= n; i++)
            scanf("%d", &m);
        sort(x + 1, x + n + 1);
        int j = n;
        r[n + 1] = 0;
        for (int i = n; i >= 1; i--)
        {
    
    
            while (j >= 1 && x[i] - x[j] <= k)
                j--;
            j++;
            l[i] = i - j + 1;
        }
        for (int i = 1; i <= n; i++)
            l[i] = max(l[i], l[i - 1]);
        j = 1;
        for (int i = 1; i <= n; i++)
        {
    
    
            while (j <= n && x[j] - x[i] <= k)
                j++;
            j--;
            r[i] = j - i + 1;
        }
        for (int i = n; i >= 1; i--)
            r[i] = max(r[i], r[i + 1]);
        int ans = 0;
        for (int i = 1; i <= n; i++)
            ans = max(ans, l[i] + r[i + 1]);
        printf("%d\n", ans);
    }
}

猜你喜欢

转载自blog.csdn.net/yangzijiangac/article/details/108895281