HDU-1421 - Mueva el dormitorio

Descripción del Título:

Mover el dormitorio es muy agotador y xhd tiene una experiencia profunda. El tiempo se remonta al 9 de julio de 2006, ese día xhd se vio obligado a pasar del edificio 27 al edificio 3 debido al cierre del edificio el día 10. dormitorio. n elementos, xhd comenzó a estar aturdido, porque n es un número entero menor que 2000, es demasiado, por lo que xhd decidió mover 2 k piezas en el pasado. Pero todavía estará muy cansado, porque 2 k no es demasiado pequeño, no es un no Un número entero mayor que n. Afortunadamente, basado en años de experiencia en mover cosas, xhd encuentra que la fatiga de cada movimiento es proporcional al cuadrado de la diferencia de peso entre la izquierda y la derecha. artículos entregados. Por ejemplo, si xhd sostiene un artículo con un peso de 3 en su mano izquierda y un artículo con un peso de 6 en su mano derecha, su nivel de fatiga después de moverse esta vez es (6-3) ^ 2 = 9 Ahora el pobre xhd quiere saber cuál es la mejor condición después de mover estos 2 * k elementos (es decir, la menor fatiga), por favor dígaselo.

ingresar:

Cada conjunto de datos de entrada tiene dos filas, la primera fila tiene dos números n, k (2 <= 2 * k <= n <2000). La segunda fila tiene n números enteros que representan el peso de n elementos (el peso es uno A entero positivo menor que 2 ^ 15).

Producción:

En correspondencia con cada conjunto de datos de entrada, solo hay un dato de salida que representa su menor fatiga, cada fila.

Ideas:

  • El análisis muestra que si se va a minimizar el valor de fatiga, los elementos que se mueven cada vez deben tener la menor diferencia de peso, por lo que los datos deben ordenarse primero.
  • Utilice una matriz bidimensional dp [i] [j] para representar la fatiga mínima de los primeros i elementos movidos j veces. En primer lugar, podemos saber que los dos primeros elementos se mueven una vez y la fatiga mínima es el cuadrado de la diferencia entre los dos primeros pesos, luego los primeros 3 ¿Qué tal si mueves cada elemento a la vez? En este momento se reflejan las ventajas de la programación dinámica. El tercer ítem se puede seleccionar o no. Si no se selecciona, es el resultado de mover los dos primeros ítems una vez. Ya se ha calculado. No es necesario repetir el cálculo. Si lo desea, entonces debe ser el cuadrado de la diferencia entre el segundo y el tercer elemento, y así sucesivamente. Para los primeros 4 elementos, encuentre el valor más pequeño de los primeros 3 elementos y el tercero y cuarto, lo que sea más pequeño, hasta el enésimo elemento
  • Luego muévete dos veces. Si mueves dos veces, debes comenzar con 4 piezas. El valor mínimo de mover 4 piezas dos veces es 1 y 2, 3 y 4, así que ¿qué tal si mueves 5 piezas dos veces? Si no elige el quinto elemento, la respuesta es mover los primeros 4 elementos dos veces. Si lo desea, es mover los primeros tres elementos una vez más los elementos cuarto y quinto. Hasta que n piezas se muevan k veces
  • Ecuación de transferencia:
    dp[j][i]=min(dp[j-1][i],dp[j-2][i-1]+pow(a[j]-a[j-1],2));

Código:

#include <iostream>
#include <cstring>
#include <algorithm> 
#include <cmath>
using namespace std;
int n,k,ans;
int a[2005];
int dp[2001][1001];//dp[i][j]表示前i件物品,搬j次最低疲劳度 
int min(int x,int y)
{
    
    
	return x<y?x:y;
}
int main()
{
    
    
	while(cin>>n>>k)
	{
    
    
		ans=0;
		memset(dp,0,sizeof(dp)); 
		for(int i=1;i<=n;i++)
		{
    
    
			cin>>a[i];
		}
		sort(a+1,a+n+1);
		for(int i=1;i<=k;i++)//搬的次数 
		{
    
    
			dp[i*2][i]=dp[i*2-2][i-1]+pow(a[i*2]-a[i*2-1],2);//先计算前i*2件搬i次消耗的疲劳值
			for(int j=i*2+1;j<=n;j++)//物品数 
			{
    
    
				dp[j][i]=min(dp[j-1][i],dp[j-2][i-1]+pow(a[j]-a[j-1],2));
			}
		}
		cout<<dp[n][k]<<endl;		
	}
	
	return 0;
} 

Supongo que te gusta

Origin blog.csdn.net/weixin_45102820/article/details/114037502
Recomendado
Clasificación