优先队列

2019暑期集训第一次校赛-C 构造B数组
链接:https://ac.nowcoder.com/acm/contest/1068/C
来源:牛客网

题目描述
给一个长度为n的数组a,现在要你构造一个长度为n的数组b,使得数组b的元素总和恰好为m且每个元素最小值不能小于0,且在这里插入图片描述 最小,求出这个最小值
输入描述:
第一行输入两个数n,m (1 <= n, m <= 1e5)

第二行输入n个数表示ai(1 <= ai <= 1e3)
输出描述:
一个数,表示答案
示例1
输入
复制
3 1
1 2 3
输出
复制
21
示例2
输入
复制
3 5
1 1 2
输出
复制
1

思路
要a[i] * (a[[i]-b[i]) * (a[[i]-b[i])的和最小,不妨令数组b的元素全为0,在尝试性对b的每元素加1,其差值越大则说明对这个b[i]加1对最后结果的贡献越忧,最后结果要求a[i] * (a[[i]-b[i]) * (a[[i]-b[i])的和最小。则每一轮尝试性给每个b加1,选出差值最大的给其b[i]加1,进行m轮此操作最后形成的b数组则能符合要求
题解

#include<iostream>
#include<queue>
using namespace std;
struct node
{
    int a,b,cz;
    bool operator < (const node& st)const{   //优先队列<号比出大小,默认大的值在顶部 ,值越大优先级就越大 
        return cz<st.cz;                     //sort函数<号比出大小,默认小的在前面 
         
    }
    
};
priority_queue<node> pt;
node st;
void zz(node st)
{  
    st.cz=st.a*(st.a-st.b)*(st.a-st.b)-st.a*(st.a-st.b-1)*(st.a-st.b-1);  
    pt.push(st);
    return ;
}
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        cin>>st.a;
        st.b=0;
        zz(st);
    }
    for(int i=1;i<=m;i++)
    {
        st=pt.top();
        pt.pop();
//        cout<<st.a<<' '<<st.b<<' '<<st.cz<<endl;
        st.b++;
        zz(st);
        
    }
    long long sum=0;
    for(int i=1;i<=n;i++)
    {
    	if(!pt.empty())
    	{
    		st=pt.top();
            pt.pop();
            sum+=st.a*(st.a-st.b)*(st.a-st.b);
		}
        
    }
    cout<<sum<<endl; 
    
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值