acwing-- codiciosos Problemas Intervalo

1. Gama de

1. La elección de la gama sitio

Ideas algoritmo:
1. En primer lugar de todas las secciones en el extremo derecho en orden ascendente
Si el orden ascendente extremo izquierdo, aparecerá
la sección una sección B anterior, se prefiere el extremo derecho de una sección, que dará lugar no está incluido en el intervalo de b cualquier punto.
Aquí Insertar imagen Descripción

2. La sección de posicionamiento en el extremo derecho y el punto final izquierdo del siguiente segmento, y si un intervalo para encontrar el punto izquierdo y el extremo derecho de la sección de posicionamiento,
este caso indica que la sección intermedia tiene dos neutral, el extremo derecho de la colocación sobre este intervalo, hasta el final del ciclo.
3. El problema es equivalente al número de cuántos disjuntos intervalo de buscar más.

Justificar: Supongamos que respondemos años, es la búsqueda de cnt, con el fin de demostrar cnt = ans, si pueden probar ans≤ y ans≥cnt.
(1) Es evidente que ans≤cnt;
(2) debido a que las condiciones en el cnt incremento de tiempo no es una intersección de dos intervalos, de modo marcar estos intervalos disjuntos es necesario para todas las secciones de la marca, por lo que la respuesta final debe ser mayor que o ya igual marcada el número de veces que ans≥cnt.
Lo prueba: ans = cnt

#include <iostream>
#include <algorithm>

using namespace std;

typedef pair<int , int> PII;
const int N = 100010;

PII range[N];//first是右端点 second是左端点 

int ans;

int main()
{   
    int n;
    cin >> n;
    
    for(int i = 0 ; i < n ; i ++)
        cin >> range[i]. second >> range[i].first;
        
    sort(range , range + n);
    
    int  r = -2e9;
    for(int i = 0;  i < n ; i++)
    {
        if(range[i].second > r)
        {
            ans++;
            r = range[i].first;
        }
    }
    
    cout << ans << endl;
    
    
    
    return 0;
}

2. El número máximo de intervalos disjuntos

Algoritmo de pensamiento: exactamente el mismo rango de punto de código seleccionado
justifica:
suponiendo que el último número es el más grande ans, el número se obtiene res.
De acuerdo con la pregunta anterior buscamos res puntos, lo que indica un máximo de resolución de intervalos que no lo hacen se cruzan. Si hay ans intervalos no se cruzan, y ans> res, debe elegir la American National Standard puntos de los recorridos de cada intervalo, pero el punto se ha determinado res viajado lo suficiente para satisfacer todos los puntos, lo que indica la American National Standard intervalos disjuntos no existe .

代码同上

3. Intervalo de paquete

Título: Dada N cerrada intervalo [A I , B I ], se pueden dividir en varios grupos de estos intervalos, de modo que (inclusive) no hay intersección, y tan pequeño como sea posible para que el número de grupos entre dos secciones interiores en cada grupo.

algoritmo Pensando:
1. El primer punto del intervalo en el orden ascendente izquierda;
2. Declarar una pequeña raíz montón para mantener la derecha de cada grupo del punto más a la derecha
3. Cada sección determina un nuevo intervalo de punto de izquierda [i] .First y pequeña el extremo derecho de la raíz de la heap.top montón (),
si heap.pop ()> = rango [i ] .First, descrito allí no es un gran suficiente para el nuevo conjunto intervalo , una necesidad de crear un nuevo grupo de súper;
de lo contrario, la nueva sección de descarga en el extremo derecho del grupo de mínima, es decir, el punto más a la derecha heap.top () del grupo (con tal de que puede acomodar la nueva sección de la descarga, en el que el conjunto mínimo directamente en el punto justo por conveniencia).
Actualización de la nueva sección de punto de ajuste derecha de añadido / creado 4.
(1) del nuevo grupo, directamente a la gama [i] .SECOND para apilar;
(2) añadido a un grupo existente, el punto del conjunto de pop más a la derecha montón, y el punto extremo derecho de la nueva gama de empuje puede ser.

Justificar: ANS se establece el intervalo mínimo, el intervalo es la búsqueda de CNT
1. Obviamente ANS <CNT =
2. Cuando abrimos a las combinaciones de CNT-1, el extremo izquierdo de la sección siguiente si el extremo derecho ≤ todos los grupos el extremo derecho, entonces necesitará abrir una combinación, este intervalo de tiempo .First grupos [i] CNT y tener una intersección (punto de la orden ascendente izquierda tal como está, el extremo derecho de la nueva sección de lo que hay una relación existente entre el grupo puntos pequeños sección caso), es decir, a la izquierda, combinado con él CNT un punto común, es necesario en grupos menos cnt, es decir ans≥cnt.
se prueba: ans = cnt

#include <iostream>
#include <queue>
#include <algorithm>

using namespace std;

const int N = 100010;

int n;

pair<int , int> range[N];

int main()
{
    cin >> n;
    
    for(int i = 0 ; i < n ; i++)
        cin >> range[i].first >> range[i].second;
        
    sort(range , range + n);
    
    priority_queue<int , vector<int> , greater<int>> heap;
    
    for(int i = 0 ; i < n ; i++)
    {
        if(heap.empty() || heap.top() >= range[i].first) ;
        else    heap.pop();
        
        heap.push(range[i].second);
    }
    
    cout << heap.size() << endl;
    return 0;
}

4. La sección de tapa

Título: Dada N cerrada intervalo [A I , B I ] y un intervalo de segmento [s, t], se elige para minimizar el intervalo, el segmento de línea especificado intervalo completamente cubierto.
Número mínimo de secciones de salida, si no cubre completamente las salidas -1.

Algoritmos ideas:
1. En primer lugar ordenados en orden ascendente punto izquierdo;
2. Punto de partida para st encontrar pt menos dejó intervalo de puntos, y seleccionar la más amplia gama punto correcto, con el punto final derecho de actualización st;
3. Si no puede encontrar la izquierda punto st es menor que el intervalo o ciclo a través de todas las secciones del rango dado no pueden ser cubiertos o -1.

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 100010;

pair<int , int> range[N];

bool success;
int st , ed;
int ans;
int n;

int main()
{
    cin >>st >> ed >> n;
    
    for(int i = 0 ; i < n ; i++)
        cin >> range[i].first >> range[i].second;
        
    sort(range , range + n);
    
    for(int i = 0 ; i < n ; i++)
    {
        int j = i , r = -2e9;//r用来记录右端点最远的点
        while(j < n && range[j].first <= st)
            r = max(r , range[j++].second);
            
        if(r < st)
        {
            ans = -1;
            break;
        }
        
        ans++;
        if(r >= ed)
        {
            success = true;
            break;
        }
        
        st = r;
        i = j  -1;
    }
    
    if(!success) ans = -1;
    cout << ans << endl;
    return 0;
}
Publicado 14 artículos originales · ganado elogios 3 · Vistas 348

Supongo que te gusta

Origin blog.csdn.net/Stephen_Zhao0/article/details/105207316
Recomendado
Clasificación