[haoi2010]工厂选址

某地区有m座矿,其中第i号矿每年产量为ai吨,现有火力发电站一个,每年需用煤b吨,每年运行的固定费用(包括折旧费,不包括煤的运费)为h元,每吨原煤从第i号矿运到原有发电厂的运费为Ci0(i=1,2,…,m;j=1,2,…,n)。
现规划新建一个发电厂,m座煤矿每年开采的原煤将全部供给这两座发电厂。现有n个备选的厂址。若在第j号备选厂址建新厂,每年运行的固定费用为hi元。每吨原煤从第i号矿运到j号备选厂址的运费为Cij(i=1,2,…,m;j=1,2,…,n)。
试问:应把新厂厂址选取在何处?m座煤矿开采的原煤应如何分配给两个发电厂,才能使每年的总费用(发电厂运行费用与原煤费用之和)为最小。

 

 

题解:贪心;

这题比较直接,只让求使费用最小,没有收益这一项限制,所以一维的贪心就够了;

主要操作:排序;

提醒:答案可能超出int范围,以及注意数组范围;

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<ctime>
#include<algorithm>
#include<cstdlib>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<cmath>
using namespace std;
#define FILE "dealing"
#define LL long long 
#define up(i,j,n) for(int i=j;i<=n;i++)
#define pii pair<LL,LL>
#define piii pair<LL,pair<LL,LL> >
template<typename T> inline bool chkmin(T &a,T b){return a>b?a=b,true:false;}
template<typename T> inline bool chkmax(T &a,T b){return a<b?a=b,true:false;}
namespace IO{
    char *fs,*ft,buf[1<<15];
    inline char gc(){return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;}
    inline int read(){
        LL x=0;int ch=gc();bool f=0;
        while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=gc();}
        while(ch<='9'&&ch>='0'){x=(x<<1)+(x<<3)+ch-'0';ch=gc();}
        return f?-x:x;
    }
}using namespace IO;
namespace OI{
    const LL maxn(50100),inf(100000000000LL),mod(10000);
    int M,B,H,N;
    int a[maxn],h[maxn],c[55][maxn];
    struct node{
        int id,d;
        inline bool operator<(const node& b)const{return d<b.d;}
    }e[maxn];
    void slove(){
        M=read(),B=read(),H=read(),N=read();
        up(i,1,M)a[i]=read();
        up(i,1,N)h[i]=read();
        up(i,0,N)up(j,1,M)c[i][j]=read();//由j厂运到i位置
        LL Min=inf,Id;
        up(i,1,N){
            up(j,1,M)e[j].id=j,e[j].d=c[0][j]-c[i][j];
            sort(e+1,e+M+1);
            LL sum=0,t=0;
            up(j,1,M){
                if(sum<B){
                    sum+=a[e[j].id];
                    t+=c[0][e[j].id]*a[e[j].id];
                    if(sum>B){
                        t=t-(sum-B)*c[0][e[j].id]+(sum-B)*c[i][e[j].id];
                        sum=B;
                    }
                }
                else t+=c[i][e[j].id]*a[e[j].id];
            }
            t+=H+h[i];
            if(t<Min)Min=t,Id=i;
        }
        printf("%I64d\n%I64d\n",Id,Min);
    }
}
int main(){
    freopen(FILE".in","r",stdin);
    freopen(FILE".out","w",stdout);
    using namespace OI;
    slove();
    return 0;
}

 

posted @ 2016-10-27 17:22  CHADLZX  阅读(297)  评论(0编辑  收藏  举报