bzoj2426: [HAOI2010]工廠選址(貪心)

Hanks_o發表於2018-03-08

題目傳送門

解法:
貪心唄。
列舉每個選址。
因為老發電廠b噸是固定的。
那麼我們先搞完他的然後剩下的全部分給新的發電廠。
那麼我們用每個礦的新電廠-老電廠花費。
這樣結果越大的用在老電廠越優。
按照這個排一下貪心搞下即可。

程式碼實現:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
int a[51000],h[110],map[61][51000];
struct node {int a,c1,c2,cha,s;}s[51000];
bool cmp(node n1,node n2) {return n1.cha>n2.cha;}
int ans[110],mmin;
int main() {
    int m,b,n;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",&map[i][j]);mmin=999999999;
    for(int i=1;i<=n;i++) {
        for(int j=1;j<=m;j++) {s[j].s=a[j];s[j].a=a[j];s[j].c1=map[0][j];s[j].c2=map[i][j];s[j].cha=map[i][j]-map[0][j];}
        sort(s+1,s+1+m,cmp);int t=b,sum=0;
        for(int j=1;j<=m;j++) {
            if(t!=0) {
                if(t>=s[j].s) {t-=s[j].s;sum+=s[j].s*s[j].c1;}
                else {sum+=t*s[j].c1+(s[j].s-t)*s[j].c2;t=0;}
            }else sum+=s[j].s*s[j].c2;
        }ans[i]=sum+h[0]+h[i];mmin=min(mmin,ans[i]);
    }
    for(int i=1;i<=n;i++)if(ans[i]==mmin) {printf("%d\n%d\n",i,ans[i]);return 0;}
    return 0;
}