Peipei

上面是我的 logo 叽哩嘎啦哈哈哈哈
蒟蒻的 Q 啦:1208247864 owo dalao 们来加啦


这个题啊,真像个费用流
然而呢 费用流也能跑
就是可能不 AK (我没试,不知道啊)
然后呢,我们考虑正解


首先我们知道我们要把所有的点放给两侧,使之最后 ans 最小
那么,我们又发现 m 是如此的小,那我们枚举好了


我们既然要求两边都小,那我们先确定一边好了
然后,我们记录所有 m 个煤矿的一个变量 del

del[i] = c[i][0]-c[i][to];
to 是现在枚举的另一个新工厂

然后根据 del[i] 把所有的煤矿排序,在前面取够 b 个
剩下的全给另一个 to
最后加上两个工厂的 h
更新 ans 就好了


#include <bits/stdc++.h>
#define II int
#define IL inline
#define R register
#define I 100100
using namespace std;

IL void of(R II &a) {
    R char c=getchar (); R II w=1, p=0;
    while (c<'0' || c>'9') { if(c=='-') w=-1; c=getchar (); }
    while (c>='0' && c<='9') { p=p*10+c-'0'; c=getchar (); }
    a=w*p;
}

/* -------------------- Peipei -------------------- */

II m,b,n,ans=1e9,WEI;
II H[I];

struct owo {
    II a,del; II c[55];
    friend bool operator < (owo a1,owo a2) {
        return a1.del<a2.del;
    }
} D[I];

int main()
{
    of(m); of(b); of(H[0]); of(n);
    for(R II i=1;i<=m;i++) of(D[i].a);
    for(R II j=1;j<=n;j++) of(H[j]);
    for(R II j=0;j<=n;j++)
    for(R II i=1;i<=m;i++) of(D[i].c[j]);

    for(R II i=1;i<=n;i++)
    {
        R II wei=1, all=b, W=0, now;
        for(R II j=1;j<=m;j++) 
            D[j].del=D[j].c[0]-D[j].c[i];
        sort(D+1,D+m+1);

        while (all) {
            now=min(all,D[wei].a);
            all-=now;
            W+=(D[wei].del+D[wei].c[i])*now;
            if(D[wei].a==now) wei++, now=0;
        }

        while (wei<=m) {
            W+=D[wei].c[i]*(D[wei].a-now);
            now=0; wei++;
        }

        if(ans>W+H[i]+H[0]) WEI=i;
        ans=min(ans,W+H[i]+H[0]);
    }

    printf("%d\n%d\n",WEI,ans);
    exit(0);
}
分类: 文章

P`eipei

Why Be King When Can Be God.

0 条评论

发表回复

Avatar placeholder

您的电子邮箱地址不会被公开。 必填项已用 * 标注