Odd-Even Subsequence 解題報告

題目鏈接:https://codeforces.ml/contest/1370/problem/D

Ashish has an array aa of size nn.

A subsequence of aa is defined as a sequence that can be obtained from aa by deleting some elements (possibly none), without changing the order of the remaining elements.Consider a subsequence ss of aa. He defines the cost of ss as the minimum between:

  • The maximum among all elements at odd indices of ss.
  • The maximum among all elements at even indices of ss.

Note that the index of an element is its index in ss, rather than its index in aa. The positions are numbered from 11. So, the cost of ss is equal to min(max(s1,s3,s5,),max(s2,s4,s6,))min(max(s1,s3,s5,…),max(s2,s4,s6,…)).

For example, the cost of {7,5,6}\left\{7,5,6\right\} is min(max(7,6),max(5))=min(7,5)=5min(max(7,6),max(5))=min(7,5)=5.

Help him find the minimum cost of a subsequence of size kk.

比較明顯能看得出思路是二分答案,然後一種思路是將數列排序後取若干相間隔的數,但這樣的話會有個問題:數列兩端點的數取與不取的情況很難討論。

因此考慮另一種思路:順序取數,用一個bool變量記錄當前取的是奇數位還是偶數位,對於奇數位/偶數位取數時保證其滿足小於等於mid,對於偶數位/奇數位則無限制條件。這種貪心思路爲什麼成立呢?

假設我們遇到了一個滿足條件的數,它的下一個數也滿足條件,那這時應該取哪個數呢?這個就是貪心的核心思想,顯然,取的數越前越好,因此直接取當前數即可。

代碼:

#include<cstdio>
#include<algorithm>
using namespace std;
 struct newdata
 {
  int label;
  long long x;
 };
 newdata a[200005];
 int b[200005];
 int n,k;
bool cmp(newdata i,newdata j)
{
 return i.x < j.x;
}
int main()
{
 scanf("%d%d",&n,&k);
 for (int i = 1;i <= n;i ++)
 {
  a[i].label = i;
  scanf("%I64d",&a[i].x);
  b[i] = a[i].x;
 }
 sort(a + 1,a + n + 1,cmp);
 int l = 1;
 int r = n;
 while (l < r)
 {
  int mid = l + r >> 1;
  int cnt = 0;
  bool now = false;
  for (int i = 1;i <= n;i ++)
   if (now)
   {
    cnt ++;
    now ^= 1;
   }
   else
   {
    if (b[i] <= a[mid].x)
    {
     cnt ++;
     now ^= 1;
    }
   }
  if (cnt >= k)
  {
   r = mid;
   continue;
  }
  cnt = 0;
  now = true;
  for (int i = 1;i <= n;i ++)
   if (now)
   {
    cnt ++;
    now ^= 1;
   }
   else
   {
    if (b[i] <= a[mid].x)
    {
     cnt ++;
     now ^= 1;
    }
   }
  if (cnt >= k)
   r = mid;
  else l = mid + 1;
 }
 printf("%d",a[l].x);
 return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章