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; }