[LuoGu] P3957의 돌 차기

\ (\ 컬러 {빨간색} {\ mathcal {설명}} \)

돌 차기 놀이도 점프 항공기로 알려진, 그것은 전세계 아이들의 게임을 중국의 전통 민속 스포츠 게임 중 하나입니다.

다음과 같이 게임의 돌 차기 놀이 규칙은 다음과 같습니다

도면에 적합한 시작점에이어서, 지상에 시작점을 결정 \ (n \) 사각형,이 격자는 동일한 행에있다. 각 격자 내의 번호 (정수)가이 도달 할 수있는 그리드 얻어진 점수를 나타낸다. 첫 번째 선수가 처음부터 바로 이동, 그리드 내에서 시작 지점의 오른쪽으로 이동합니다. 두 번째 시간 등 오른쪽으로 현재 위치에서 이동을 계속하고 있습니다. 규칙 :

각 플레이어는 현재 위치의 오른쪽에 그리드 내에서 이동해야합니다. 플레이어는 언제든지 게임을 종료 오버에 도달 그리드의 숫자의 합에 대한 점수를 얻을 수 있습니다.

RR 이제이 게임에 참석하기 위해 점프 작은 로봇을 개발했다. 그러나이 로봇은 바운스는 고정 될 수 오른쪽에서 시간, 매우 심각한 결함을 가지고 \ (d 개 \)를 . RR 그가 보내는 경우, 자신의 작은 로봇을 개선하기 위해 희망 \ (g의 \) 자신의 로봇을 개선하기 위해 금화를, 그래서 그는 로봇의 유연성이 증가 할 수있을 것입니다 \ (g의 \)를 , 그것은 주목해야한다, 적어도 모든 거리 바운스 그 되고 (1 \) \ . 구체적으로,시 \는 (g <D \) , 그 로봇의 오른쪽마다 선택할 수 반송 거리 \ (DG \) \ (DG. 1 + \) \ (DG + 2 \) , ... \ (D + G-2 \) \ (D + G- 1 \). \ (D + G \) , 그렇지 않은 경우 (경우 \ (g \ GEQ D \) ), 그의 로봇 각 반송 오른쪽 거리 선택할 수 \을 (. 1 \)를 \ (2 \) \이 . (3 \)를 , ... \ (D + G-2 \) \ (D-G. 1 + \) , \ (D + G \) .

이제 작은 \ (R \) 적어도 싶어 \ (케이 \) 는 적어도 자신의 로봇을 변환하는 데 걸리는 많은 금 내가 그에게 포인트를.

\ (\ 컬러 {빨간색} {\ mathcal {입력 \ 형식}} \)

세 개의 양의 정수의 첫 줄 \ (\ N-) , \ (D \) , \ (K \) , 각 격자의 수를 개선 반송 고정 거리는 로봇 전에 적어도 얻어지는 원하는 분획을 나타낸다. 인접한 두 숫자 사이의 공간에 의해 분리된다.

다음 \ (\ N-) 두 개의 양의 정수의 라인 \ (x_i로부터 \) , \ (S_I \) 각각의 시점에 \ (I는 \) 의 격자와 부에서 \ (I는 \) 사각형 점수. 두 숫자 사이의 공백으로 구분. 확인 (x_i로부터 \) \를 오름차순으로 입력된다.

\ (\ 컬러 {빨간색} {\ mathcal {출력 \ 형식}} \)

총 행, 많은 동전이 자신의 로봇을 변환하는 이상 지출하는 방법을 나타내는 정수. 어떤 경우에는, 그는 적어도 얻을 수없는 경우 \ (케이 \) 점, 출력 \을 (--1 \) .

\ (\ 컬러 {빨간색} {\ mathcal {DataSize \ 계약}} \)

데이터 만족 모두에게 \ (1 ≤ ≤ N-500000 \.) , \ (≤2000 1 ≤ D \.) , \ (1 ≤ x_i로부터, K ≤ 10. 9 ^ \.) , \ (| S_I |. <105 ^ \)

\ (\ 컬러 {빨간색} {\ mathcal {해결}} \)

출력의 경우 \ (--1 \) 상황 모든 점수가 양수가 도달 할 수없는 그리드를 추가 할 것입니다 \ (케이 \) 포인트

테스트 사이트이 질문에 절반 답하고 단조로운 큐 최적화의 선수이다 \이 (DP \)가 주인이 대답의 절반에 상상하기 어려운 일이 아니다 (\ 확인) \ 선형 사용할 때 \ (DP \)를 ,하지만 그렇게 만하고 \ ( 50 \) 포인트

상태의 설계되도록에서는 \는 (DP가 [I]가 \) 섹션 나타내는 \ (나는 \) 은 다음과 같이 격자가 전사 방정식이있을 때 획득 될 수있는 최대 점수 :

\ [DP [I] = 최대 \ {DP [J] \} w [내가] \ \ \ \ \ \ (나는 당량 N, POS [I] -maxd \ 당량의 j 개의 \의 당량 볼때 \ 1 \ 당량 [I + ]-마음)\]

전용 전송 간격 것으로 \가 ([pos가 [I]를 -maxd , POS는 [I]를 뒤에 조심] \) 내에 \ (DP가 [j]가 \) 최대 수 있으므로 모노톤 대기열을 고려할 수는이 범위 유지 \을 ( DP [J] \) 최대

코드가 특히 복잡하지 달성하기 위해, 관심을 열고 \ (롱 \ 긴 \)를 하고, 그리드에 도달 여부를 결정 작업을

\ (\ 컬러 {빨간색} {\ mathcal {코드}} \)

#include <bits/stdc++.h>
#define LL long long
#define reg register
using namespace std;

const int kN = 5e5 + 10;
const LL inf = 0x3f3f3f3f3f3f3f3f;

LL dp[kN];
int x[kN], w[kN];
int N, D, K, Ans = -1;
deque< LL > q;

bool ok(int g) {
  if (!q.empty()) q.clear();
  for (reg int i = 0; i <= N; ++i)
    dp[i] = -inf;
  int mind = max(1, D - g), maxd = D + g;
  int las = 0;
  dp[0] = 0LL;
  for (reg int i = 1; i <= N; ++i) {
    while (x[las] < x[i] - maxd) las++;
    while (x[las] <= x[i] - mind && x[las] >= x[i] - maxd && las < i) {
      while (!q.empty() && dp[las] >= dp[q.back()]) q.pop_back();
      q.push_back(las++);
    }
    while (!q.empty() && x[q.front()] < x[i] - maxd) q.pop_front();
    if (!q.empty())dp[i] = dp[q.front()] + w[i];
    if (dp[i] >= K) return true;
  }
  return false;
}

int main() {
  scanf("%d%d%d", &N, &D, &K);
  LL ck = 0;
  for (reg int i = 1; i <= N; ++i)
    scanf("%d%d", &x[i], &w[i]), ck += (w[i] < 0 ? 0 : w[i]);
  if (ck < K) return puts("-1"), 0;
  int lb = 0, rb = x[N], Mid;
  while (lb <= rb) {
    Mid = (lb + rb) >> 1;
    if (ok(Mid)) Ans = Mid, rb = Mid - 1;
    else lb = Mid + 1;
  }
  printf("%d\n", Ans);
  
  return 0;
}

\ (\ 컬러 {빨간색} {\ mathcal {출처}} \)

\ (NOIp PJ \ T4 \ \ 2017 \)

추천

출처www.cnblogs.com/1miharu/p/11333116.html