Campamento de entrenamiento multiescuela de verano de Niuke 2020 (tercera sesión) E. Estructura de dos emparejamientos + dp

Enlace de tema: E.Two Matchings

Título

Vamos a construir dos secuencias p, q de longitud n. Las dos secuencias tienen bits diferentes y satisfacen pi ≠ i y ppi = i {p_i ≠ i y p_ {p_i} = i}pagsyo=yo y ppagsyo=yo . Dada una secuencia a, puedes calcular un valor(∑ i = 1 nabs (ai - api)) / 2 {(\ sum_ {i = 1} ^ {n} abs (a_i-a_ {p_i})) / 2}( i = 1na b s ( ayo-unapagsyo) ) / 2 Encuentre la suma más pequeña de valores calculados entre pyq que cumplen las condiciones.

responder

Esta pregunta analiza primero la secuencia de p y q. La pregunta da pi ≠ i y ppi = i {p_i ≠ i y p_ {p_i} = i}pagsyo=yo y ppagsyo=i , de hecho, la secuencia de p, q es equivalente a una, dos, tres ... n intercambiar posiciones una vez. Dado que n es un número par, no habrá tal cosa como un intercambio de posiciones varias veces.
Si es necesario(∑ i = 1 nabs (ai - api)) / 2 {(\ sum_ {i = 1} ^ {n} abs (a_i-a_ {p_i})) / 2}( i = 1na b s ( ayo-unapagsyo) ) / 2 es el más pequeño, entonces podemos determinar fácilmente una secuencia primero, es decir, después de ordenar la secuencia a, se pueden intercambiar cada dos adyacentes.

Entonces, ¿cómo determinar el segundo valor más pequeño?
Si n = 4, entonces la secuencia del siguiente valor más pequeño es: 4 1 3 2
n = 4
Si n es 6, entonces la secuencia del siguiente valor más pequeño es: 6 3 2 5 4 1
n = 6
Al principio estaba pensando por qué no cuando n = 6: 3 1 4 2 6 5, y finalmente encontramos que es la misma que la secuencia que construimos por primera vez: 2 1 4 3 6 5 Los dos últimos dígitos son iguales, lo que no es adecuado para el propósito.

Ahora que conocemos el valor mínimo de n = 4 y n = 6, ¿todavía necesitamos enumerar el valor mínimo de n = 8,10 ...?
Por supuesto que no, mcd (4, 6) = 2 {mcd (4,6) = 2}g c d ( 4 ,6 )=2. Según el teorema de Pei Shu en la teoría de números,4 k 1 + 6 k 2 = mcd (4, 6) = 2 {4k_1 + 6k_2 = mcd (4,6) = 2}4 k1+6 k2=g c d ( 4 ,6 )=2 tiene solución, entonces significa quela suma de múltiplos de 4 y múltiplos de 6 debe ser un múltiplo de 2.
La implicación es que se conoce el valor mínimo de 4 y 6, y el n (número par) restante se puede resolver mediante recursividad.

Sea dp [i]: el valor mínimo de la suma de los i números anteriores.
Inicialización:
dp [2] = inf
dp [4] = a [4] + a [3] -a [2] -a [1]
dp [6] = a [6] + a [5] -a [4 ] + a [3] -a [2] -a [1]
Entonces la ecuación de transición de estado es:
dp [n] = min (dp [i-4] + a [i] + a [i-1] -a [ i-2] -a [i-3],
dp [i-6] + a [i] + a [i-1] -a [i-2] + a [i-3] -a [i-2 ] -a [i-1])

Código

#include<iostream>
#include <sstream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<bitset>
#include<cassert>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<deque>
#include<iomanip>
#include<list>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
using namespace std;
//extern "C"{void *__dso_handle=0;}
typedef long long ll;
typedef long double ld;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define pii pair<int,int>
#define lowbit(x) x&-x
//#define int long long

const double PI=acos(-1.0);
const double eps=1e-6;
const ll mod=1e9+7;
const ll inf=1e18;
const int maxn=2e5+10;
const int maxm=100+10;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);

ll a[maxn];
ll dp[maxn];
int main()
{
    
    
	int t;
	scanf("%d",&t);
	while(t--)
	{
    
    
		int n; scanf("%d",&n);
		for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
		sort(a+1,a+1+n);
		ll sum=0;
		for(int i=2;i<=n;i+=2) sum+=a[i]-a[i-1];
		dp[2]=inf;
		dp[4]=a[4]+a[3]-a[2]-a[1];
		dp[6]=a[6]+a[5]+a[3]-a[4]-a[2]-a[1];
		for(int i=8;i<=n;i+=2)
		{
    
    
			dp[i]=min(dp[i-4]+(a[i]+a[i-1]-a[i-2]-a[i-3]),
			(dp[i-6]+a[i]+a[i-1]-a[i-2]+a[i-3]-a[i-4]-a[i-5]));
		}
		sum+=dp[n];
		printf("%lld\n",sum);
	}
}

Supongo que te gusta

Origin blog.csdn.net/weixin_44235989/article/details/108399478
Recomendado
Clasificación