fjutacm 3872 mundo algoritmo de búsqueda binaria primera falsa

Descripción del problema

un día, la caída va a montar pa, él ve una chica muy hermosa

Viene al caso, la práctica reciente Cuelgue esquivar, esquivar rápido de hardware es el tipo que puede pasar a la segunda etapa, el nivel de la primera planta, con el fin de esquivar la práctica, el Hang llevará a cabo el entrenamiento diario, por lo que en una recta ------ en una línea recta, primero marcará Cuelgue n puntos, y calcula la distancia entre los dos puntos de cada uno, el n-th puntos Cuelgue necesidad de saltar desde el primer punto. Si el punto salta de izquierda a derecha º punto, la distancia de salto es una [l] + a [l + 1] + ... una [r-2] + a [r-1], como Cuelgue perezoso, así que se levantó de un salto a poco menos de k, y cada ubicación debe estar en n marcar puntos, un salto debería al menos pedir Cuelgue salto lejos? (No se puede saltar a la máxima distancia, la ubicación debe ser marcado en el punto)

 

Entrada

La primera fila es n, k, 1 <= n, k <= 1e5

n-1 enteros segunda fila, representa a [i] -> i-ésima distancia entre el primer punto hasta el punto i + 1 1 <= a [i] <= 1e5;

 

Salida

Salida de una sola línea, representa la máxima distancia cada vez que necesita para saltar

 

SampleInput

6 3 
1 3 2 2 5

SampleOutput

5

1->3 4
3->5 4
5->6 5
最远距离为5

Esta pregunta y yo escribimos otro blog - cortar la cuerda con el mismo propósito, una dicotomía es encontrar la respuesta. Esta pregunta es difícil de pensar, con la idea de que el código es relativamente fácil de lograr.

Y cortar la cuerda a medida que avanzamos a la mitad de la respuesta, volvió a cumplir con las condiciones de respuestas, la mayor parte del número requerido de pasos, que es el título de "por lo menos debería saltar lejos", que "cada vez que se necesita para saltar a la máxima distancia." Leer el título para leer bien, tal vez un significado.

Aclarar un punto, queremos que, en el caso del número de condición de pasos, caminando lo más pequeño posible, es decir, nos encontramos con la respuesta, para hacer una serie de pasos necesarios para terminar todo lo más grande posible sin exceder k.

Por lo tanto, los primeros puntos de ventaja. En primer lugar, el borde izquierdo de un poco menos de la mitad de un máximo en la línea, ya que hay que asegurarse de que todo el proceso de pasar, de lo contrario el número de pasos necesarios puede ser visto como pase infinita, directa cabo, sólo mayor que la suma de un límite a la derecha en la línea, porque muchos gran paso es todo lo mismo, sin necesidad de perder tiempo. En cuanto a la razón por la frontera no es igual, se puede ir a ver a otro blog en el blog I a media pensión acción, los jefes escribieron.

En segundo lugar, mi aritmética está caminando a juzgar por el tamaño actual, el número de pasos necesarios para terminar el todo es mayor que la condición de la serie de medidas con el fin de reducir el tamaño del pie de fronteras, por lo que en primer lugar, que el ciclo continúa hasta la intersección de la frontera, Si res == k volvemos, y no ser capaz de obtener el mínimo de caminar. Y debido a que el inicio de la zona de relajación inicial, el uso de la palabra forma "abierta izquierda derecha abierta", y que queremos es lo más pequeño posible caminar, por lo que el retorno final de Intercambio r (debido a la holgura borde izquierdo también, y también es límite "abierto", que toma un valor mínimo en la intersección, el l indeseable).

Luego, en el código, ver los comentarios.

#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <stack>
#include <queue>
#include <vector>
#include <math.h>
#include <iostream>
#include <string.h>
const int MAX=1e5+5;
using namespace std;
typedef long long ll;
ll a[MAX], maxx, sum;
ll td(int n, ll k)
{
  ll l=maxx-1, r=sum+1, m, now;
  int i, j, res;
  while (l+1<r)
  {
    res = 0;  /// 初始化当前解所需步数
    now = 0;  /// 初始化临时跳过的距离
    m = (l+r)/2;
    for (i=1; i<n; i++)  /// 遍历一遍柱子
    {
      if (now+a[i]>m)  /// 这一跳,跳不到下一根柱子了
      {
        now = a[i];   /// 更新位移,从这一根柱子到下一根柱子的距离开始
        res ++;       /// 这一跳算是在这里结束了,记跳了一次
      }
      else
        now += a[i];  /// 能跳过去就加上

      if (res>k)      /// 步履太小,还没跳完步数就超了,直接可以break准备开始
        break;        ///下一次循环了
    }
    if (now)
      res ++;  /// 最后一跳也结算一下
    if (res>k) /// 需要的步数超了,说明步履不够大
      l = m;
    else       /// 反之,说明步履大小还有缩小的可能性
      r = m;
  }
  return r;
}
int main()
{
  ll k;
  int n, i;
  cin >> n >> k;
  maxx = 0;
  sum = 0;
  ll ans=0;
  for (i=1; i<n; i++)
  {
    scanf("%lld", &a[i]);
    maxx = max(maxx, a[i]);
    sum += a[i];
  }
  ans = td(n, k);
//  if (ans>maxx) cout << ans << endl;
//  else cout << maxx << endl;
  cout << ans << endl;
  return 0;
}

 

Se han publicado 19 artículos originales · ganado elogios 0 · Vistas 507

Supongo que te gusta

Origin blog.csdn.net/qq_43317133/article/details/98590125
Recomendado
Clasificación