codeforce 557C Arthur and Table (思维)

原题地址:http://codeforces.com/problemset/problem/557/C

题意:

一个桌子有n个桌腿,每个桌腿长l,砍断需要体力d,欲使桌子保持平衡,需要砍断部分桌腿,使得剩余的桌腿中长度最大的那些桌腿的数量大于剩余桌腿数量的一半

求使桌子保持平衡最少需要花费的体力

题解:

以某长度Li的桌腿作为最长桌腿,那么大于Li的桌腿全部砍去,小于的部分则砍去最少的,花费最小的桌腿,不断枚举Li,用基排的思想,复杂度n*d;

#include<bits/stdc++.h>

#define clr(x,y) memset((x),(y),sizeof(x))

using namespace std;
typedef long long LL;

const int maxn=1e5;
const int inf=1e9;

struct P
{
    int l,d;
    bool operator < (const P& rhs) const
    {
        return l>rhs.l;
    }
};

P p[maxn+5];
int dnum[205];


int main(void)
{
    #ifdef ex
    freopen ("../in.txt","r",stdin);
    //freopen ("../out.txt","w",stdout);
    #endif

    int n;
    scanf("%d",&n);

    for (int i=1;i<=n;++i)
    {
        scanf("%d",&p[i].l);
    }
    for (int i=1;i<=n;++i)
    {
        scanf("%d",&p[i].d);
        ++dnum[p[i].d];
    }

    sort(p+1,p+1+n);

    int s=1;
    int cnt=n;
    int ans=inf;
    int cost=0;
    for (int i=1;i<=n;++i)
    {
        if (i!=n && p[i].l==p[i+1].l) continue;
        int temp=cost;
        for (int j=s;j<=i;++j)
        {
            --dnum[p[j].d];
            cost+=p[j].d;
        }

        int n1=i-s+1;
        int n2=cnt-2*n1+1;
        for (int j=1;j<=200;++j)
        {
            if (n2<=0) break;

            int k=min(n2,dnum[j]);
            n2-=k;
            temp+=j*k;
        }

        ans=min(ans,temp);

        cnt-=(i-s+1);
        s=i+1;
    }

    printf("%d
",ans);
}
原文地址:https://www.cnblogs.com/123-123/p/5572229.html