[HAOI2010] 工厂选址 - 贪心

\(m \leq 5\times 10^4\) 座煤矿,产量分别为 \(a_i \leq 500\),火力发电厂每年需要用 \(b \leq 10^4\) 单位煤,每年运行的固定成本为 \(h \leq 100\),煤从 \(i\) 运送到发电厂的单价为 \(C_{i,0} \leq 50\)。现在计划新建一个发电厂,且所有煤矿开采的煤都供给这两个发电厂。有 \(n \leq 50\) 个备选厂址,第 \(j\) 个的固定运行费用是 \(h_j\leq 100\),从煤矿 \(i\) 到厂址 \(j\) 的运费单价为 \(C_{i,j} \leq 50\)。求最优的规划方案,包括如何选择新厂厂址和如何将原煤分配给两个工厂。

Solution

考虑到 \(n\) 很小,直接枚举选哪个新工厂

双代价不好处理,但由于实际 work 的只是它们的差,不妨将所有煤全部运送到新工厂的代价计算出来,然后对于一个运送到旧工厂的,我们只需要将它的代价差值作为代价即可

在计算出这样的相对代价后,我们只需要贪心地选出最小相对代价的 \(b\) 单位的煤即可

#include <bits/stdc++.h>
using namespace std;

const int N = 50005;

struct item {
    int x,y;
    bool operator < (const item &b) {
        return x < b.x;
    }
} d[N];

int n,m,a[N],b,h[N],c[N][55];

int solve(int pos) {
    int ans=0;
    for(int i=1;i<=m;i++) ans+=c[i][pos]*a[i];
    for(int i=1;i<=m;i++) d[i].x=c[i][0]-c[i][pos], d[i].y=a[i];
    sort(d+1,d+m+1);
    int rem=b;
    for(int i=1;i<=m;i++) {
        int tmp=min(rem,d[i].y);
        rem-=tmp;
        ans+=tmp*d[i].x;
    }
    return ans;
}

signed main() {
    cin>>m>>b>>h[0]>>n;
    for(int i=1;i<=m;i++) cin>>a[i];
    for(int i=1;i<=n;i++) cin>>h[i];
    for(int i=0;i<=n;i++) for(int j=1;j<=m;j++) cin>>c[j][i];
    int ans=1e18,x=0;
    for(int i=1;i<=n;i++) {
        int tmp=solve(i)+h[i];
        if(tmp<ans) {
            ans=tmp;
            x=i;
        }
    }
    cout<<x<<endl<<ans+h[0]<<endl;
}

猜你喜欢

转载自www.cnblogs.com/mollnn/p/12389861.html