2019牛客暑期多校训练营(第七场)C-Governing sand

题面描述:有一片树林,要求砍掉一些树,使得最高的树的数量占总数量的一半以上,每种树有高度,数量,以及砍掉需要的花费。求最小花费。

思路:将每种树按高度排序后,从低到高枚举最高的树的高度,然后判断最小花费。cost最多200,每次查询最多两百次,时间足够。

比当前最高的树需要全部砍掉,可以预处理答案,枚举时实时修改。要注意的是不同树的高度可能不同,计算数量时要考虑,另外修改已有树的数量要在当前高度的树处理完毕后,否则会对计算结果造成干扰。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mem(a) memset(a,0,sizeof a)
#define pii pair<int,int>
const int N=1e5+5;
const int INF=1e9+5;
ll read(ll &a){scanf("%lld",&a);return a;}
int read(int &a){scanf("%d",&a);return a;}
int read(){int a;scanf("%d",&a);return a;}
int read(int &a,int &b){scanf("%d %d",&a,&b);return a;}
int n;
struct node{
    ll h,c,p;
}a[N];
ll leftans;
//ll leftcnt;
ll cnt[210];
void scan(){
    leftans=0;
    //leftcnt=0;
    for(int i=0;i<n;i++){
            scanf("%lld%lld%lld",&a[i].h,&a[i].c,&a[i].p);
            leftans+=a[i].c*a[i].p;
            //leftcnt+=a[i].p;
    }
}
bool cmp(node x,node y){
    return x.h<y.h;
}
void solve(){
    sort(a,a+n,cmp);
    //a[n].h=0;
    mem(cnt);
    ll high=0;
    ll highcnt=0;
    ll needcut=0;
    ll ans=1e18+7;
    ll temp;
    ll all=0;
    queue<node>q;
    for(int i=0;i<n;i++){
        //leftcnt-=a[i].p;
        leftans-=a[i].p*a[i].c;
        all+=a[i].p;
        temp=leftans;
        if(a[i].h>high){
            highcnt=a[i].p;
            while(!q.empty()){
                cnt[q.front().c]+=q.front().p;
                q.pop();
            }
        }
        else highcnt+=a[i].p;
        high=a[i].h;
        needcut=all-(highcnt+highcnt-1);
        if(needcut>0){
            for(int j=1;j<=200&&needcut>0;j++){
                if(needcut>=cnt[j]){
                    needcut-=cnt[j];
                    temp+=cnt[j]*j;
                }
                else{
                    temp+=needcut*j;
                    needcut=0;
                    break;
                }
            }
        }
        ans=min(ans,temp);
        q.push(a[i]);
        //cnt[a[i].c]+=a[i].p;
    }
    printf("%lld\n",ans);
}
int main()
{
    while(~scanf("%d",&n)){
        scan();
        solve();
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/CGKirito/p/11327544.html