1. 程式人生 > >2426: [HAOI2010]工廠選址 貪心

2426: [HAOI2010]工廠選址 貪心

Description

某地區有m座煤礦,其中第i號礦每年產量為ai噸,現有火力發電廠一個,每年需用煤b噸,每年執行的固定費用(包括折舊費,不包括煤的運費)為h元,每噸原煤從第i號礦運到原有發電廠的運費為Ci0(i=1,2,…,m)。

現規劃新建一個發電廠,m座煤礦每年開採的原煤將全部供給這兩座發電廠。現有n個備選的廠址。若在第j號備選廠址建新廠,每年執行的固定費用為hj元。每噸原煤從第i號礦運到j號備選廠址的運費為Cij(i=1,2,…,m;j=1,2,…,n)。

試問:應把新廠廠址選取在何處?m座煤礦開採的原煤應如何分配給兩個發電廠,才能使每年的總費用(發電廠執行費用與原煤運費之和)為最小。

Input

第1行: m b h n

第2行: a1 a2 … am (0<=ai<=500, a1+a2+…+an>=b)

第3行: h1 h2 … hn (0<=hi<=100)

第4行: C10 C20 … Cm0 (0<=Cij<=50)

第5行: C11 C21 … Cm1

                          …   …

第n+4行:C1n C2n … Cmn

Output

第1行:新廠址編號,如果有多個編號滿足要求,輸出最小的。

第2行:總費用

Sample Input

4 2 7 9

3 1 10 3

6 3 7 1 10 2 7 4 9

1 2 4 3

6 6 8 2

4 10 8 4

10 2 9 2

7 6 6 2

9 3 7 1

2 1 6 9

3 1 10 9

4 2 1 8

2 1 3 4

Sample Output

8

49

HINT

對於所有資料, n<=50, m<=50000, b<=10000

題解:

失蹤人口又回來更新一波部落格,列舉工廠放到哪,先把所有的煤全部給一個,更新另一個的權值,貪心每次取最小即可

#include<cstdio>
#include<cstdlib>
#include<ctime> #include<cmath> #include<cstring> #include<string> #include<iostream> #include<iomanip> #include<algorithm> using namespace std; int m,b,n; int a[50010]; int h[100]; int cost[51][50100]; int val[50100]; int id[50100]; bool cmp(int x,int y) { return val[x]<val[y]; } long long calc(int t) { long long ans=0; for(int i=1;i<=m;i++) ans+=1ll*cost[t][i]*a[i]; ans+=h[0]+h[t]; for(int i=1;i<=m;i++) { id[i]=i; val[i]=cost[0][i]-cost[t][i]; } sort(id+1,id+1+m,cmp); int tmp=b; for(int i=1;i<=m && tmp;i++) { if(tmp>=a[id[i]]) { ans+=1ll*a[id[i]]*val[id[i]]; tmp-=a[id[i]]; } else { ans+=1ll*tmp*val[id[i]]; tmp-=tmp; } } return ans; } int main() { scanf("%d%d%d%d",&m,&b,&h[0],&n); for(int i=1;i<=m;i++) scanf("%d",&a[i]); for(int i=1;i<=n;i++) scanf("%d",&h[i]); for(int i=0;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&cost[i][j]); long long ans=214748364700000000ll; int idd; for(int i=1;i<=n;i++) { int t=calc(i); if(t<ans) { ans=t; idd=i; } } cout<<idd<<endl<<ans<<endl; }