B. Most socially-distanced subsequence(思维+模拟)

B. Most socially-distanced subsequence

题意:
给出一个数组 a a a,找到数组中的一个子序列 s s s(长为 x x x),满足“ ∑ i = 1 x ∣ s [ i ] − s [ i − 1 ] ∣ \sum_{i=1}^x|s[i]-s[i-1]| i=1xs[i]s[i1]最大”。如果有多个答案就出 x x x较小的子序列

思路:
我们观察一个递增的序列 s = { 1 , 2 , 3 , 4 , 6 } s = \{1,2,3,4,6\} s={ 12346},则:
∑ i = 1 x ∣ s [ i ] − s [ i − 1 ] ∣ = 5 \sum_{i=1}^x|s[i]-s[i-1]| = 5 i=1xs[i]s[i1]=5,因为 s [ i ] > s [ i − 1 ] s[i] > s[i-1] s[i]>s[i1],所以当我们拆开公式,发现只剩下 s [ 5 ] − s [ 1 ] = 6 − 1 = 5 s[5] - s[1] = 6-1 = 5 s[5]s[1]=61=5,同理当序列递减也有同样的结论。(解决了最短的问题)。
在这里插入图片描述
序列 { x , z , y } \{x,z,y\} { x,z,y},如果在数轴上 z z z x , y x,y xy中间(如 z 1 z_1 z1), ∣ y − z ∣ + ∣ z − x ∣ = y − x |y-z|+|z-x| = y-x yz+zx=yx,如果像 z 2 z_2 z2一样,我们可以发现 ∣ y − z ∣ + ∣ z − x ∣ = z − y + z − x |y-z|+|z-x| = z-y+z-x yz+zx=zy+zx,这个找到 ∑ i = 1 x ∣ s [ i ] − s [ i − 1 ] ∣ \sum_{i=1}^x|s[i]-s[i-1]| i=1xs[i]s[i1]最大和 x x x最小用到的方法都是一样的。

剩下的就是我们的模拟了,找出数组a中连续的递增或递减的序列,除去中间的元素,不影响结果。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5+10;
const int inf = 0x7ffffff;
const ll INF  = 0x7fffffffffff;
ll f[][2] = {
    
    1, 0, 0, 1, -1, 0, 0, -1}, n, m;
ll s[N];
int read() {
    
    
    int x = 0; int f = 1; char s = getchar();
    while(s < '0' || s > '9') {
    
    if(s == '-') f = -1; s = getchar();}
    while(s >= '0' && s <= '9') {
    
    x = (x << 3) + (x << 1) + s - 48; s = getchar();}
    return x * f;
}
int main() {
    
    
    // freopen("in.txt", "r", stdin);
    // freopen("out.txt", "w", stdout);
    int t;
    cin >> t;
    while(t--) {
    
    
        n = read();
        m = n;
        for(int i=1; i<=n; i++) s[i] = read();
        if(n == 2) {
    
    
            cout << 2 << endl;
            for(int i=1; i<=n; i++) cout << s[i] << ' ';
            cout << endl; 
            continue;
        }
        int i = 1, j = 2, k = 3;//从数组下标1,2,3开始扫描,每三个三个比较。
        while(k <= n) {
    
    
        	//判断是否连续递增或
            if(s[j]>s[i] && s[k]>s[j] || s[j]<s[i] && s[j]>s[k]) {
    
    
                m--;
                s[j] = -1;/做标记。
                j++, k++;
            }
            else i = j, j++, k++;
        }
        cout << m << endl;
        for(int i=1; i<=n; i++) {
    
    
            if(s[i] != -1) cout << s[i] << ' ';
        }
        cout << endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_45363113/article/details/107436931