bzoj 2937: [Poi2000]建造酿酒厂

最优酿酒厂选址算法

2937: [Poi2000]建造酿酒厂

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 67   Solved: 23
[ Submit][ Status][ Discuss]

Description

Abstinence 岛上的居民很喜欢饮用纯酿的啤酒。迄今为止,他们都是从波兰进口啤酒,自己不生产。但今年岛上的一个城市决定建造一个酿酒厂,供给其他城市的啤酒需求。
岛上所有的城市都环绕在海岸线上,相邻两城之间用高速公路连接(也就是说,它们近似分布在一个圆上)。对于建造酿酒厂的城市来说,它将得到的信息是其余城市对于啤酒的日需求量,并且还有一张记载着相邻两城市之间距离的表格。经过计算,每一桶啤酒每英里的运费为一泰勒。每天的成本为所有城市的运费之和,前提是每个城市的日需求量必须得到满足。可以看出,日成本与酿酒厂建造位置是息息相关的。我们的问题是:为投资者找出最理想的酿酒厂位置,使得日成本最小。
 

Input

第一行包含一个数 n ,为城市数目, 5<=n<=10000 (我们假设城市已经沿着海边高速公路顺序编号,为 1 2 …… n ,对于 1<=i<n ,编号为 i 的城市的下一个城市为 i+1 ,而 n 号城市的下一个城市为 1 号)。接下来的 n 行每行包含两个数字。第 i+1 行的两个数字为 表示的是 i 号城市的日需求量, 则表示 i 号城市与它的下一个城市之间的距离(单位:英里)。海边高速公路的总长度不大于 1000000 英里 ,所有城市啤酒的日需求量不大于 1000

Output

 
仅包含一个数,为所求最小的日成本。

Sample Input

6
1 2
2 3
1 2
5 2
1 10
2 3

Sample Output

41

HINT

Source

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
long long n,m,a[20003],b[20003];
long long sum[20003],d[20003];
int main()
{	scanf("%lld",&n);
	for (int i=1;i<=n;i++)
	{
		scanf("%lld%lld",&a[i],&b[i]);
		a[i+n]=a[i]; b[i+n]=b[i];
	}
    for (int i=1;i<=n<<1;i++)
    {
    	sum[i]=sum[i-1]+a[i];
    	d[i]=d[i-1]+b[i-1];
    }
    long long now=0;
	for (int i=2;i<=n;i++)
	 now+=a[i]*min(d[i],d[n+1]-d[i]);
	long long x=1;
	while (d[x+1]<d[n+1]-d[x+1]) x++;
	long long k=1;  long long ans=now;
	for(int i=2;i<=n;++i){  
        now+=(long long)b[i-1]*(sum[n+i-1]-sum[x]-(sum[x]-sum[i-1]));  
        while (d[x+1]-d[i]<d[n+i]-d[x+1])
		  now+=(long long)a[x+1]*(d[x+1]-d[i]-(d[n+i]-d[x+1])),
		  x++;
		if (ans>now)  
         ans=min(ans,now),k=i;
    }    
	printf("%lld\n",ans);
	return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值