intさわだんのBlack History

刹那的レジェンドになりたい。

第9回日本情報オリンピック 本選 「つらら」

ちょっと考えたら解法が浮かんでくるのではないだろうか。


解法:
d[i]をi番目のつららの長さとする。
まず、一番長いつららd[i]が折れるのにかかる時間はL-d[i]である。


次に、二番目にながいつららについて、その両隣のどちらかに自分より長いつらら(つまり一番長いつらら)がある場合は”一番ながいつららの折れる時間” + ”二番目に長いつららの折れる時間"が二番目に長いつららが折れる時間となる。
両隣がどちらも自分より短い場合は”L - 自分のつららの長さ” となる。

このように1番目にながいつららからN番目に長いつららの折れるまでにかかる時間をpriority_queueなどを使い、求めることができる。その折れる時間の最大値が解。

計算量はO(N).

#include <cstdio>
#include <queue>
#include <utility>
#include <algorithm>

using namespace std;
typedef pair<int,int> P;
int n,l,d[100003],s[100003];
int ans = 0;

int main(){
  scanf("%d%d",&n,&l);
  priority_queue<P> que;
  for(int i = 1;i <= n;i++){
    scanf("%d",&d[i]);
    que.push(P(d[i],i));
  }
  
  while(que.size()){
    P q = que.top(); que.pop();
    s[q.second] = max(s[q.second-1],s[q.second+1]) + l - q.first;
    ans = max(ans,s[q.second]);
  }
  printf("%d\n",ans);
  
  return 0;
}