B. Most socially-distanced subsequence (thinking + simulation)

B. Most socially-distanced subsequence

Question:
Give an array aaa , find a subsequencessin the arrays (length isxxx),满足“ ∑ i = 1 x ∣ s [ i ] − s [ i − 1 ] ∣ \sum_{i=1}^x|s[i]-s[i-1]| i=1xs[i]s[i1 ] | . Maximum "If there is more than one answer liesxxx smaller subsequence

Idea:
We observe an increasing sequence 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 ] , so when we disassemble the formula, we find that onlys [5] − s [1] = 6 − 1 = 5 s[5]-s[1] = 6-1 = 5s[5]s[1]=61=5. Similarly, when the sequence is decreasing, the same conclusion can be obtained. (Solved the shortest problem).
Insert picture description here
Sequence{x, z, y} \{x,z,y\}{ x,with ,y } , if on the number linezzz x , y x,y between x and y (such asz 1 z_1with1) ,∣ y - z ∣ + ∣ z - x ∣ = y - x | yz | + | zx | = yxyz+zx=andx if it is likez 2 z_2with2In the same way, we can find ∣ y − z ∣ + ∣ z − x ∣ = z − y + z − x |yz|+|zx| = z-y+zxyz+zx=withand+withx , this finds∑ i = 1 x ∣ s [i] − s [i − 1] ∣ \sum_{i=1}^x|s[i]-s[i-1]|i=1xs[i]s[i1 ] | largest andxxThe methods used to minimize x are the same.

The rest is our simulation, to find out the continuous increasing or decreasing sequence in the array a, and remove the middle element without affecting the result.

#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;
}

Guess you like

Origin blog.csdn.net/weixin_45363113/article/details/107436931
Recommended