More than 2019 cattle off summer school camp (seventh) -C Governing sand

Topic link: https: //ac.nowcoder.com/acm/contest/887/C

Meaning of the questions: There are n trees, gives a high number for each, removing the cost and quantity, is seeking a minimum spend much so that the number of the remaining trees in the tallest trees accounted for more than half.

Thinking: height values ​​are sorted first by violence enumeration tree to which the highest tree, for each selection, to a height greater than the other full-cut tree of the tree, this can be O (n) obtained pretreatment. Then cut to a height smaller than the minimum cost of the tree so as to satisfy the condition of some trees, note c <= 200, then the number of the tree can be saved each takes from 1 to 200 to be removed enumerated the minimum amount of spending can be.

AC Code:

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

const int maxn=1e5+5;
typedef long long LL;
int n;
LL ans,num[maxn],C[205],pre,aft[maxn];
struct node{
    LL h,c,p;
}a[maxn];

inline LL read(){
    LL x=0,f=0;char ch=0;
    while(!isdigit(ch)) {f|=ch=='-';ch=getchar();}
    while(isdigit(ch)) x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
    return f?-x:x;
}

bool cmp(node x,node y){
    return x.h<y.h;
}

LL cal(LL x){
    LL res=0;
    for(int i=1;i<=200;++i){
        if(C[i]>=x){
            res+=i*x;
            break;
        }
        else{
            res+=i*C[i];
            x-=C[i];
        }
    }
    return res;
}

int main(){
    while(~scanf("%d",&n)){
        ans=0x3f3f3f3f3f3f3f3f;
        memset(C,0,sizeof(C));
        for(int i=1;i<=n;++i)
            a[i].h=read(),a[i].c=read(),a[i].p=read();
        sort(a+1,a+n+1,cmp);
        aft[n]=0;
        for(int i=n-1;i>=1;--i)
            aft[i]=aft[i+1]+a[i+1].c*a[i+1].p;
        int j;
        for(int i=1;i<=n;i=j){
            LL t1=a[i].p;
            num[i]=num[i-1]+a[i].p;
            for(j=i+1;j<=n&&a[j].h==a[i].h;++j){
                num[j]=num[j-1]+a[j].p;
                t1+=a[j].p;
            }
            LL tmp=num[j-1]-2*t1+1;
            if(tmp<=0)
                pre=0;
            else
                pre=cal(tmp);
            for(int k=i;k<j;++k)
                C[a[k].c]+=a[k].p;
            ans=min(ans,pre+aft[j-1]);
        }
        printf("%lld\n",ans);
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/FrankChen831X/p/11328610.html