Skip to Content

Rabbit Carrot

Pista

En lugar de minimizar la cantidad de postes cuyas alturas cambiamos, maximicemos la cantidad de postes cuyas alturas no cambiamos.

Condición

Sean a1,,aNa_1,\ldots,a_N las alturas de los postes. Si las alturas de los postes numerados i1<i2<<iki_1<i_2<\cdots<i_k no cambian, entonces deberíamos tener

aijMij a_{i_j}\le M\cdot i_j aij+1aij+M(ij+1ij) a_{i_{j+1}}\le a_{i_j}+M\cdot (i_{j+1}-i_j)

para todo 1j<k1\le j<k.

Pasos finales

Podemos reescribir las desigualdades de arriba como

0Mi1ai1 0\le M\cdot i_1-a_{i_1} MijaijMij+1aij+1 M\cdot i_j-a_{i_j}\le M\cdot i_{j+1}-a_{i_{j+1}}

Definiendo bi=Miaib_i=M\cdot i-a_i para cada 1iN1\le i\le N, se sigue que

0bi1 0\le b_{i_1} bijbij+1 b_{i_j}\le b_{i_{j+1}}

¡así que hemos reducido el problema a hallar la subsecuencia no decreciente más larga de bb!

#include <algorithm> #include <iostream> #include <vector> using std::cout; using std::endl; using std::vector; int longest_nondec_subseq(const vector<int> &seq) { vector<int> min_endings; for (int i : seq) { /* * notemos que usamos upper_bound en lugar de * lower_bound porque solo tiene que ser no decreciente */ int pos = std::upper_bound(min_endings.begin(), min_endings.end(), i) - min_endings.begin(); // protocolo estándar de LIS if (pos == min_endings.size()) { min_endings.push_back(i); } else { min_endings[pos] = i; } } return min_endings.size(); } int main() { int pole_num; int jump_height; std::cin >> pole_num >> jump_height; vector<int> poles(pole_num); for (int p = 0; p < pole_num; p++) { std::cin >> poles[p]; } vector<int> poss_unchanged; for (int i = 1; i <= pole_num; i++) { // solo agregamos si hay alguna esperanza de que quede sin cambiar if (i * jump_height >= poles[i - 1]) { poss_unchanged.push_back(i * jump_height - poles[i - 1]); } } cout << pole_num - longest_nondec_subseq(poss_unchanged) << endl; }
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.StringTokenizer; public class triusis { // any other name breaks the grader lmao public static void main(String[] args) throws IOException { BufferedReader read = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer initial = new StringTokenizer(read.readLine()); int poleNum = Integer.parseInt(initial.nextToken()); int jumpHeight = Integer.parseInt(initial.nextToken()); ArrayList<Integer> possUnchanged = new ArrayList<>(); for (int p = 0; p < poleNum; p++) { int pole = Integer.parseInt(read.readLine()); // solo agregamos si hay alguna esperanza de que quede sin cambiar if ((p + 1) * jumpHeight >= pole) { possUnchanged.add((p + 1) * jumpHeight - pole); } } System.out.println(poleNum - longestNondecSubseq(possUnchanged)); } private static int longestNondecSubseq(ArrayList<Integer> arr) { ArrayList<Integer> minEndings = new ArrayList<>(); for (int i : arr) { // hallamos el último lugar donde podemos insertarlo (porque solo tiene que ser // no decreciente) int pos = bisectRight(minEndings, i); // protocolo estándar de LIS if (pos == minEndings.size()) { minEndings.add(i); } else { minEndings.set(pos, i); } } return minEndings.size(); } private static int bisectRight(ArrayList<Integer> arr, int x) { int lo = 0; int hi = arr.size(); while (lo < hi) { int mid = (lo + hi) / 2; if (x < arr.get(mid)) { hi = mid; } else { lo = mid + 1; } } return lo; } }
from typing import List from bisect import bisect_right def longest_nondec_subseq(arr: List[int]) -> int: min_endings = [] for i in arr: # bisect_right no left porque solo tiene que ser no decreciente pos = bisect_right(min_endings, i) # protocolo estándar de LIS if pos == len(min_endings): min_endings.append(i) else: min_endings[pos] = i return len(min_endings) pole_num, jump_height = [int(i) for i in input().split()] poles = [int(input()) for _ in range(pole_num)] poss_unchanged = [] for i, p in enumerate(poles): if (i + 1) * jump_height >= p: poss_unchanged.append((i + 1) * jump_height - p) print(pole_num - longest_nondec_subseq(poss_unchanged))

Extra: ¿Se puede resolver el caso en que el conejo puede saltar a lo sumo MM unidades hacia abajo y a lo sumo MM unidades hacia arriba?

Spoiler

Sea bib_i como se definió arriba, y sea ci=Mi+aic_i=M\cdot i+a_i. Entonces deberíamos tener tanto bijbij+1b_{i_j}\le b_{i_{j+1}} como cijcij+1c_{i_j}\le c_{i_{j+1}}.

Así que basta hallar la cantidad máxima de triples distintas de la forma (i,bi,ci)(i,b_i,c_i) tales que

(i1,bi1,ci1)(i2,bi2,ci2)(ik,bik,cik), (i_1,b_{i_1},c_{i_1})\ll (i_2,b_{i_2},c_{i_2})\ll \cdots \ll (i_k,b_{i_k},c_{i_k}),

donde (x1,x2,x3)(y1,y2,y3)(x_1,x_2,x_3)\ll (y_1,y_2,y_3) significa que xjyjx_j\le y_j para j[1,3]j\in [1,3]. Primero, descartemos el primer elemento de cada triple. La respuesta sigue siendo la misma que si conserváramos el primer elemento, ya que bijbij+1b_{i_j}\le b_{i_{j+1}} y cijcij+1c_{i_j}\le c_{i_{j+1}} juntos implican que ijij+1i_j\le i_{j+1}.

Así que ahora el problema es hallar la cantidad máxima de pares distintas de la forma (bi,ci)(b_i,c_i) tales que

(bi1,ci1)(bi2,ci2)(bik,cik), (b_{i_1},c_{i_1})\ll (b_{i_2},c_{i_2})\ll \cdots \ll (b_{i_k},c_{i_k}),

Esto se puede hacer ordenando los puntos (bi,ci)(b_i,c_i) en orden creciente de coordenada bb (desempatando por coordenada cc), y ejecutando un algoritmo de LIS sobre las coordenadas cc.