F. Maratón de la cerveza (dos puntos + iteración + codicioso)

Inserte la descripción de la imagen aquíInserte la descripción de la imagen aquíInserte la descripción de la imagen aquí
El significado de esta pregunta es fácil de entender, pero no es fácil de escribir.
El significado de la pregunta: dé las posiciones de n cabinas iniciales, y luego mueva estas cabinas para que la distancia entre las dos cabinas sea k; encuentre la suma de las distancias de movimiento más pequeñas;
también entendí este problema después de leer la solución;
porque somos ¿No se mueve siempre a la misma distancia al final?
El significado es (asumimos que el punto de inicio es un [0], n = 4):
Inserte la descripción de la imagen aquí
Entonces, ¿se moverá al estilo anterior al final;
luego, podemos pasar cada coordenada dada por el título a la posición correspondiente arriba? ; por
ejemplo, supongo que el punto de partida es 1, 2, 3, 4 (donde k es 1), y las coordenadas iniciales dadas por el título son 0, 1, 2, 5;
entonces podemos 0-1, 1 -2, 2 -3,5-4; el resultado es -1, -1, -1,1; ¿es correcto?
Entonces podemos encontrar el problema; si asumimos que el punto de partida es 1, entonces la posición dada en el título eventualmente cambiará a las posiciones de 1, 2, 3, 4;
entonces puedo averiguar si la suma de los valores absolutos de las diferencias anteriores es la distancia total de movimiento; porque esta es solo la respuesta cuando Supongamos que el punto de partida está a la 1 en punto, pero requerimos esto y mínimo. De hecho, se puede suponer que el punto de partida está en otras coordenadas, pero al final todo se convertirá en esta forma:
Inserte la descripción de la imagen aquí
Entonces, ¿podemos dividir el punto de partida?
Por cierto, la idea está aquí, pero ¿cuál es el intervalo de inicio?
Esta pregunta es un poco metafísica, por qué es porque abrí la segunda partición a 1e12 para pasarla, y también usé el método iterativo;
de hecho, la idea de esta pregunta ya se entiende, es enumerar el punto de partida , y luego seguir registrando la respuesta mínima;
de hecho, esta pregunta es un poco como Los valores máximo y mínimo en el libro blanco son los mismos (dos puntos + codicioso); pero este problema todavía tiene iteraciones. . . . Mayor conocimiento;
consulte el código para obtener más detalles:
Código de CA:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,k;
ll a[1000010];
ll sum(ll d){
    
    //这个函数就是用来计算初始值和最终值的差值的和,也就是最终移动的距离
	ll res=0;
	for(int i=0;i<n;i++){
    
    
		  res+=abs(a[i]-d);
		  d+=k;
	}
	return res;
}
int main(){
    
    
	cin>>n>>k;
	for(ll i=0;i<n;i++)cin>>a[i];
	sort(a,a+n);//题目输入并没有顺序,所以需要排序
	ll l=-1e12,r=1e12;//二分起点坐标
	ll t1,t2;
	ll ans=1e18;//记录答案
	for(ll i=0;i<100;i++){
    
    
		ll L=l+(r-l)/3,R=r-(r-l)/3;//这里为什么不用L=l,R=r?就是迭代的知识,只不过这点确实不好想
		  t1=sum(L);
		  t2=sum(R);
		  if(t1<t2){
    
    
		  	 r=R;
		  }else {
    
    
		     l=L;
		  }
		  ans=min(ans,min(t1,t2));
		  //cout<<t1<<t2<<endl;
	}
	cout<<ans<<endl;
	return 0;
}

Supongo que te gusta

Origin blog.csdn.net/qq_44555205/article/details/104450507
Recomendado
Clasificación