当前位置:   article > 正文

Codeforces Round #311 (Div. 2)-C(杂题——(终于紫名辣!!

codeforces 紫名

题意:桌子有若干个腿,只有长度最长的腿的数目是所有腿的数目的一半以上的时候才是稳定的,去掉每个腿有一个花费,现在问最小花费是多少

思路:注意这个题有个关键点就是d的值非常小,只有200,实际上这个问题可以总结为下面这个问题:前x个数中最小的k个数的和是多少?只要解决这个问题,本题也就迎刃而解了,而这个子问题由于d很小,可以记录d值出线的次数,然后O(d)暴力就好,当然也可以二分,更快。

然后这一场终于第一次紫名了!!!感觉努力了一年还是有点成果的。。虽然只是刚刚上1700,但是这对我来说意义重大!!

#include<bits/stdc++.h>
#define pb push_back
using namespace std;
typedef long long ll;
const int maxv=2e5+50;
int n;
struct S{
    int l,d;
}T[maxv];
bool cmp(S a,S b){
    return a.l<b.l;
}
vector<S> V;
int contd[303];
int getless(int x){
    if(x<=0) return 0;
    int add=0,cont=0;
    for(int i=1;i<205;i++){
        if(cont+contd[i]>=x){
            return add+i*(x-cont);
        }else{
            cont+=contd[i];
            add+=i*contd[i];
        }
    }
}
int sumsq[maxv];
int main(){
    ///freopen("/home/files/CppFiles/in","r",stdin);
    cin>>n;
    int tol=0;
    for(int i=0;i<n;i++) scanf("%d",&T[i].l);
    for(int i=0;i<n;i++){
        scanf("%d",&T[i].d);
        tol+=T[i].d;
    }
    sort(T,T+n,cmp);
    sumsq[0]=T[0].d;
    for(int i=1;i<n;i++){
        sumsq[i]=sumsq[i-1]+T[i].d;
    }
    int lastmax=-1;
    int maxnum=0;
    int ans=1e9;
    int sum=0;
    int maxsum=0;
    for(int i=0;i<n;i++){
        if(T[i].l!=lastmax){
            lastmax=T[i].l;
            maxnum=1;
            maxsum=T[i].d;
            int k=i+1;
            while(k<n&&T[k].l==T[i].l){
                maxnum++;
                maxsum+=T[k].d;
                k++;
            }
            ans=min(ans,tol-sumsq[k-1]+getless(k-maxnum-(maxnum-1)));
            contd[T[i].d]++;
        }else{
            contd[T[i].d]++;
        }
    }
    cout<<ans<<endl;
    return 0;
}
View Code

 

转载于:https://www.cnblogs.com/Cw-trip/p/4612217.html

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/72543
推荐阅读
相关标签
  

闽ICP备14008679号