CodeForces#311 C. Arthur and Table

题意:

给出一个桌子,有n个腿,每个腿的长度是l,拆掉这条腿的花费是d,当最长的腿占腿总数大于其他腿的总数,那么合法,问到达合法情况的最小代价。


解题思路:

首先根据长度排个序,然后枚举每种长度作为最长长度。枚举到当前长度时,相同长度不砍,把比当前长度大的全砍掉(这个比较容易维护),然后再看现在是否已经满足条件,,不满足则从前面费用小的开始砍,直到满足为止。


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <set>
#include <queue>

#define LL long long
#define fir first
#define sec second
using namespace std;

int n;
LL num[233333],s[233333],maxl,cost,ans,sl[233333];
pair<LL,LL>leg[233333];
multiset<LL>q;
//priority_queue<LL,vector<LL>,greater<LL> >q;
LL gao[233333];

int main(){
    ans=(LL)2333333333333333;
    scanf("%d",&n);
    memset(sl,0,sizeof(sl));maxl=0;memset(num,0,sizeof(num));
    for(int i=1;i<=n;i++){scanf("%I64d",&leg[i].fir);maxl=max(maxl,leg[i].fir);}
    for(int i=1;i<=n;i++)scanf("%I64d",&leg[i].sec);
    sort(leg+1,leg+1+n);
    for(int i=1;i<=n;i++){num[leg[i].fir]++;sl[leg[i].fir]+=leg[i].sec;}
    for(int i=1;i<=maxl;i++)s[i]=s[i-1]+sl[i];
    int j=1;
    for(int i=1;i<=maxl;i++){
        if(s[i]==s[i-1])continue;
        cost=0;
        while(leg[j].fir<i)j++;
        set<LL>::iterator it=q.end();
        if(!q.empty())it--;
        for(int k=1;k<=num[i]-1;k++){
            if(q.empty())break;
            cost+=*it;
            if(it==q.begin())break;
            it--;
        }
        cost=s[i-1]-cost;
        cost+=s[maxl]-s[i];
        ans=min(ans,cost);
        while(leg[j].fir==i){
            q.insert(leg[j].sec);
            if(j==n)break;
            j++;
        }
    }
    printf("%I64d\n",ans);
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值