[SSL] 1040 2004 Divisional League Improvement Group 2 Merged Fruit

[SSL] 1040 2004 Divisional League Improvement Group 2 Merged Fruit

Límite de tiempo: 20000MS Límite de memoria: 65536K
Límite de tiempo de la caja: 5000MS

Descripción

En un huerto, Duoduo ya había derribado todas las frutas y las había dividido en diferentes montones según los diferentes tipos de frutas. Duoduo decidió combinar todas las frutas en una sola pila.
  Cada vez que se fusiona, Toto puede fusionar dos pilas de frutas, y la energía consumida es igual a la suma del peso de las dos pilas de frutas. Se puede ver que después de que todas las frutas se fusionan n-1 veces, solo queda una pila. La resistencia total consumida por Duoduo al fusionar las frutas es igual a la suma de la resistencia consumida por cada fusión.
  Debido a que se necesitará un gran esfuerzo para llevar estas frutas a casa, Duoduo debería ahorrar la mayor cantidad de energía posible al fusionar las frutas. Suponiendo que el peso de cada fruta es 1 y que se conoce el número de tipos de fruta y el número de cada fruta, su tarea es diseñar un plan de secuencia combinado para minimizar la cantidad de esfuerzo físico que consume Duoduo y generar el valor mínimo. de fuerza física.
  Por ejemplo, hay 3 tipos de frutas, los números son 1, 2 y 9. Puede fusionar las pilas 1 y 2 primero, el número de pilas nuevas es 3 y el esfuerzo físico es 3. Luego, combine la nueva pila con la tercera pila original y obtenga una nueva pila, el número es 12 y el esfuerzo físico es 12. Entonces Toto consume un total de resistencia = 3 + 12 = 15. Se puede demostrar que 15 es el valor mínimo de gasto físico.

Aporte

La entrada consta de dos líneas, la primera línea es un número entero n (1 <= n <= 10000), que indica el número de tipos de frutas. La segunda línea contiene n enteros, separados por espacios El i-ésimo entero ai (1 <= ai <= 20000) es el número de la i-ésima fruta.

Producción

La salida incluye una línea, y esta línea solo contiene un número entero, que es el valor mínimo de esfuerzo físico. Ingrese datos para asegurarse de que este valor sea menor que 231.

Entrada de muestra

3 
1 2 9 

Salida de muestra

15

Pista

Para el 30% de los datos, se garantiza que n <= 1000:
Para el 50% de los datos, se garantiza que n <= 5000;
para todos los datos, se garantiza que n <= 10000.

Ideas

Utilice heap.
Primero construya una pila.
Clasificación del montón
Saque los 2 primeros del montón cada vez, súmelos e insértelos en el montón

Código

Pila de escritura a mano

#include<iostream>
#include<cstdio>
using namespace std;
int h[100010];
class heapmn
{
    
    
	private:
	public:
		void heapup(int n,int x);//上移操作,把h[x]上移的合适位置
		void heapdown(int n,int x);//下移操作,把h[x]下移的合适位置
		void heapinsert(int &n,int x);//插入操作,把x加入堆的合适位置 
		void heapdelete(int &n,int x);//删除操作,删除h[x]
		void heapsort(int &n);//堆排序 
		void heapbuild(int &n,int m);//建堆 
		void swap(int &t1,int &t2);//交换两数
};
void heapmn::swap(int &t1,int &t2)//交换两数 
{
    
    
	int t=t1;
	t1=t2,t2=t;
	return;
}
void heapmn::heapup(int n,int x)//上移操作,把h[x]上移的合适位置 
{
    
    
	if(x>n)return;
	for(;x>1;x>>=1)
		if(h[x]<h[x>>1]) swap(h[x],h[x>>1]);
		else return;
	return;
}
void heapmn::heapdown(int n,int x)//下移操作,把h[x]下移的合适位置
{
    
    
	if(x<1)return;
	for(x<<=1;x<=n;x<<=1)
	{
    
    
		x+=(x+1<=n&&h[x+1]<h[x]);
		if(h[x]<h[x>>1]) swap(h[x>>1],h[x]);
		else return;
	}
	return;
}
void heapmn::heapinsert(int &n,int x)//插入操作,把x加入堆的合适位置 
{
    
    
	h[++n]=x;
	heapup(n,n);
	return;
}
void heapmn::heapdelete(int &n,int x)//删除操作,删除h[x] 
{
    
    
	if(h[n]<=h[x]) h[x]=h[n--],heapup(n,x);
	else h[x]=h[n--],heapdown(n,x);
	return;
}
void heapmn::heapsort(int &n)//堆排序 
{
    
    
	for(;n;h[1]=h[n--],heapdown(n,1))
	{
    
    
		//a[i]=h[1];
		printf("%d ",h[1]);
	}
	return;
}
void heapmn::heapbuild(int &n,int m)//建堆 
{
    
    
	int i;
	for(n=0,i=1;i<=m;i++)
	{
    
    
	    //h[++n]=a[i];
		scanf("%d",&h[++n]);
	    heapup(n,n);
	}
	return;
}
int main()
{
    
    
	heapmn heap;
	int n,i,ans=0,tem;
	scanf("%d",&n);
	heap.heapbuild(n,n);
	while(n>1)
	{
    
    
		tem=h[1];
		heap.heapdelete(n,1);
		tem+=h[1];
		ans+=tem;
		heap.heapdelete(n,1);
		heap.heapinsert(n,tem);
	}
	printf("%d",ans);
	return 0;
}

STL

#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
priority_queue <int> que;
int main()
{
    
    
	int n,i,ans=0,tem;
	scanf("%d",&n);
	for(i=1;i<=n;i++)
	{
    
    
		scanf("%d",&tem);
	    que.push(-tem);
	}
	for(i=1;i<n;i++)
	{
    
    
		tem=-que.top();
		que.pop();
		tem-=que.top();
		que.pop();
		ans+=tem;
		que.push(-tem);
	}
	printf("%d",ans);
	return 0;
}

Supongo que te gusta

Origin blog.csdn.net/weixin_46975572/article/details/113113541
Recomendado
Clasificación