有 (m leq 5 imes 10^4) 座煤矿,产量分别为 (a_i leq 500),火力发电厂每年需要用 (b leq 10^4) 单位煤,每年运行的固定成本为 (h leq 100),煤从 (i) 运送到发电厂的单价为 (C_{i,0} leq 50)。现在计划新建一个发电厂,且所有煤矿开采的煤都供给这两个发电厂。有 (n leq 50) 个备选厂址,第 (j) 个的固定运行费用是 (h_jleq 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;
}