您的位置:首页 > 其它

罪人审判

2016-07-06 17:36 281 查看

问题描述 Problem Description

小昊是著名女帝, 阳姐•查兰•伊丽莎白一世的专属宠物。但是小昊人模人样, 尤其是公正心, 更是超乎正常人一等。 所以阳姐委任他担当最高法院最高大法官审判长一职。 今天, 大法官小昊审判了 N 个罪人, 每个人的罪恶度为 Di 。 按照惯例, 这些罪人应该要背着跟他罪恶度相等重量的荆棘游街示众。 但是因为小昊的正义过头, 导致这几天荆棘几乎卖完了, 今天只有 M 个单位重量的荆棘了。 万一某个罪人少背了 X 个单位的荆棘, 那么民众对这个罪人受到的处罚会产生 X2 的不满值。 现在小昊想知道, 如何分配仅有的荆棘, 才能使民众对这 N 个犯人产生的不满值总和最小? 对了, 因为小昊的手无法抓稳秤杆, 所以每个罪人只能背整数单位的荆棘。

输入描述 Input Description

输入第一行包含两个正整数 M 和 N, 意义如上所述。

下接 N 行, 每行一个正整数, 为每个罪人的罪恶度 Di 。

输出描述 Output Description

输出一行包含一个正整数, 代表最小的不满值总和。

输入样例 Sample Input

5 3

1

3

2

样例输出 Sample Output

1

分析 I Think

如果 x>y>0 ,则 (x−1)2>(y−1)2,利用这个我们就可以贪心求解了,每次找到最大的,让他变成次大的,消耗一些荆棘,就这样知道荆棘不够用的时候就可以了

代码 Code

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;

typedef long long LL;

struct node{
LL data,tot;
node(int d=0,int t=0){data=d;tot=t;}
bool operator < (const node &h)const{
return data < h.data;
}
bool operator > (const node &h)const{
return data > h.data;
}
};

LL m,M,n;
priority_queue<node >que;

int main(){

que.push(node(0,1));
scanf("%lld%lld",&m,&n);M=m;
for(LL i=1,a;i<=n;++i){
scanf("%lld",&a);
que.push(node(a,1LL));
M -= a;
}

if(M > 0){
printf("0");
return 0;
}

node tmp1,tmp2;
LL del,total;
while(m > 0){
tmp1 = que.top();
que.pop();
tmp2 = que.top();
que.pop();
if(tmp1.data == tmp2.data){
tmp1.tot += tmp2.tot;
que.push(tmp1);
continue;
}
del = tmp1.data-tmp2.data;
if(m >= del*tmp1.tot){
m -= del*tmp1.tot;
tmp2.tot += tmp1.tot;
que.push(tmp2);
}
else{
total = m/tmp1.tot;
m -= total*tmp1.tot;
tmp1.data -= total;
que.push(node(tmp1.data,tmp1.tot-m));
que.push(node(tmp1.data-1,m));
que.push(tmp2);
m = 0;
}
}

LL ans = 0;
while(!que.empty()){
tmp1 = que.top();
que.pop();
ans += tmp1.data*tmp1.data*tmp1.tot;
}

printf("%lld",ans);

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: