HAOI2010 工厂选址

题目链接:戳我

数组开小火葬场qwqwq

就是一个贪心吧。对于一个数,我们知道只有两种摆放方式。所以我们可以先都放到新的里面,然后做一下新的-原先的差,按照差从大到小排序,依次提取数值减去即可。

代码如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std; 
int n,m,B,H,ans=2147483647,pos,cnt;
int a[50010],h[51],c[51][50010],now[50010];
struct Node{int w,tot;}cur[50010];
inline bool cmp(struct Node x,struct Node y){return x.w>y.w;}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    #endif
    scanf("%d%d%d%d",&m,&B,&H,&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",&c[i][j]);
    for(int i=1;i<=n;i++)
    {
        int cur_ans=h[i]+H,sum=B,cnt=0;
        for(int j=1;j<=m;j++)
            cur[++cnt]=(Node){c[i][j]-c[0][j],a[j]};
        sort(&cur[1],&cur[1+cnt],cmp);
        for(int j=1;j<=m;j++)
        {
            cur_ans+=c[i][j]*a[j];
        }
        for(int j=1;j<=cnt&&sum;j++)
        {
            if(sum>=cur[j].tot)
                cur_ans-=cur[j].tot*cur[j].w,sum-=cur[j].tot;
            else
                cur_ans-=sum*cur[j].w,sum=0;
        }
        if(cur_ans<ans) ans=cur_ans,pos=i;
    }
    printf("%d\n%d\n",pos,ans);
    return 0;
}
posted @ 2019-03-01 16:33  风浔凌  阅读(93)  评论(0编辑  收藏  举报