【Greedy】【Heap】Gym - 101775B - Scapegoat

The meaning of the question: There are n events, each event has a severity, m people (m>=n), you have to let m people take the blame, each person can only take the blame for one event, but an event can be caused by many people back. Let you minimize the variance of the severity experienced by the m individuals.

Consider that each of n people recite an event at the beginning, and record the ans in the initial state. Then assign the remaining mn individuals. The severity x of each event and the current number of people y are stored in the heap, according to x*x/yx*x/(y+ 1.0) (this value is the variance*n currently provided by the event - assign one more to the current event The variance that a person can provide *n, that is, the amount of improvement that can be brought to the variance by assigning one more person to it, it is easy to deduce) Sort from large to small, and then take elements from the top of the heap in turn, and assign a person to This event can be put back into the heap, and then subtract this value from the ans of the initial state until the value of the top element of the heap is less than zero.

#include<cstdio>
#include<queue>
using namespace std;
const double EPS=0.00000001;
double ave;
struct data{
	double x,y,val;
	data(const double &x,const double &y){
		this->x=x;
		this->y=y;
		val=x*x/y-x*x/(y+1.0);
	}
	data(){}
};
bool operator < (const data &a,const data &b){
	return a.val<b.val;
}
priority_queue<data>Heap;
int a[200005];
double sqr(const double &x){
	return x*x;
}
int T,n,m;
int main(){
	//freopen("b.in","r",stdin);
	scanf("%d",&T);
	for(int to=1;to<=T;++to){
		while(!Heap.empty()){
			Heap.pop();
		}
		scanf("%d%d",&n,&m);
		ave=0;
		for(int i=1;i<=n;++i){
			scanf("%d",&a[i]);
			ave+=(double)a[i];
		}
		ave/=(double)m;
		double tt=0;
		for(int i=1;i<=n;++i){
			tt+=sqr((double)a[i]-ave);
		}
		double ans=tt+sqr(ave)*(double)(m-n);
		for(int i=1;i<=n;++i){
			Heap.push(data((double)a[i],1.0));
		}
		for(int i=1;i<=m-n;++i){
			data t=Heap.top(); Heap.pop();
			if(t.val<EPS){
				break;
			}
			Heap.push(data(t.x,t.y+1.0));
			ans-=t.val;
		}
		printf("Case #%d: %.12f\n",zu,ans/(double)m);
	}
	return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325148126&siteId=291194637
Recommended