codevs【1507】酒厂选址

题目描述
Abstinence(戒酒)岛的居民们酷爱一种无酒精啤酒。以前这种啤酒都是从波兰进口,但今年居民们想建一个自己的啤酒厂。岛上所有的城市都坐落在海边,并且由一条沿海岸线的环岛高速路连接。酒厂的投资者收集了关于啤酒需求量的信息,即每天各城市消费的啤酒桶数。另外还知道相邻城市之间的距离。每桶啤酒每英里的运费是1元。日运费是将所需要的啤酒从酒厂运到所有城市所必需的运费之和。日运费的多少和酒厂的选址有关。投资者想找到一个合适的城市来修建酒厂,以使得日运费最小。

请设计一个程序,输入城市的数目、相邻两城市间的距离以及每个城市消费的啤酒桶数,输出最小的日运费。

输入描述
第一行是一个整数n(5 <= n <= 10000) ,表示城市的数目。 城市沿高速路编号,使得相邻的城市的编号也相邻(城市1和n也被认为是相邻)。 以下的n行,每行有两个非负整数。第I+1行的数 zi、di分别是城市I每日的啤酒消费量(桶)和从城市I沿高速路到下一个城市的距离(英里)。高速路的总长不会超过65535 英里。每座城市的日消费量不会超过255桶。

输出描述
一个整数,表示所需的最小日运费(元)。

样例输入
6
1 2
2 3
1 2
5 2
1 10
2 3

样例输出
41

分析
参考了一位大神的做法,直接暴力。

#include<iostream>
using namespace std;
#define N 20000 + 10
#define INF 0x3f3f3f3f3f3f//足够大的数
#define ll long long
int n;
ll a[N],b[N],c[N];
ll sum;
ll ans = INF;
int main()
{
	cin >> n;
	for(int i = 0; i < n; i++)
		cin >> a[i] >> b[i];
		
	for(int i = 0; i < n; i++) {
		//处理环型 
		a[i + n] = a[i];
		b[i + n] = b[i];
		sum += b[i];//记录一下总长 
	}
	/*外层循环为酒厂地址,内层循环得到日运费
	因为复制了一份,变为了线性,所以只需要往后推,同时控制长度*/
	for(int i = 0; i < n; i++) {
		ll t = 0;
		for(int j = i + n - 1; j >= i + 1; j--) {//这里需要从后往前推,不理解可以模拟一下过程
			t += b[j];
			c[i] += min(t,sum - t) * a[j];//这里是将环分为两半,找到较短的一半
		}
	}
	for(int i = 0; i < n; i++)
		ans = min(ans,c[i]);
	
	cout << ans << endl;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值