Codeforces1364B Most socially-distanced subsequence (思维)
生活随笔
收集整理的這篇文章主要介紹了
Codeforces1364B Most socially-distanced subsequence (思维)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接: Most socially-distanced subsequence
大致題意
給出一個長度為n的序列p, 你需要找到p的一個子序列s, s的長度至少為2, 且|s1 - s2| + |s2 - s3| + … + |sk-1 - sk|盡可能大, 如果多個子序列的值相同, 輸出任一長度最短的子序列.
解題思路
考慮到對于上式|s1 - s2| + |s2 - s3| + … + |sk-1 - sk|進行化簡:
①假設當前序列單調遞增, 則可化簡為: (s2 - s1) + (s3 - s2) + … + (sk - sk-1) = sk - s1
②假設當前序列單調遞減, 則可化簡為: (s1 - s2) + (s2 - s3) + … + (sk-1 - sk) = s1 - sk
我們發現, 如果對于一段單調遞增 或 單調遞減的區間[l, r], 只有p[l]和p[r]是有意義的, 我們選擇其他的元素并不會使得當前序列的值增加或減少.
對于一段序列, 我們可以將其拆分成若干個互不相交的 遞增區間 和 遞減區間. 我們需要選擇每個相應區間的開頭元素和結尾元素. 這其實相當于我們選擇波峰元素和波谷元素以及p[1] 和 p[n].
AC代碼
#include <bits/stdc++.h> #define rep(i, n) for (int i = 1; i <= (n); ++i) using namespace std; typedef long long ll; const int N = 1E5 + 10; int a[N]; int main() {int t; cin >> t;while (t--) {vector<int> v;int n; scanf("%d", &n);rep(i, n) scanf("%d", &a[i]);rep(i, n) {if (i == 1 or i == n) v.push_back(a[i]);else if (a[i - 1] < a[i] and a[i + 1] < a[i]) v.push_back(a[i]);else if (a[i - 1] > a[i] and a[i + 1] > a[i]) v.push_back(a[i]);}printf("%u\n", v.size());for (auto& op : v) printf("%d ", op); puts("");}return 0; }END
總結
以上是生活随笔為你收集整理的Codeforces1364B Most socially-distanced subsequence (思维)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 以太坊目前所使用的共识算法介绍
- 下一篇: 敏感词屏蔽——AC自动机