题意:
有N座环形分布的城市,相邻城市编号相邻,现要建一座酒厂,每个城市对酒的需求不同,每桶酒每千米运费为1元。给定n各城市,所需酒的桶数以及城市间的距离,求酒厂建在哪个城市可使得运费最小。
输入:
第一行为n,代表城市个数。以下n行分别有两个整数,代表第i个城市每日需酒量和与下一座城市的距离。
输出:
输出最小运费。
可以使用枚举法,枚举酒厂在各个城市的情况,计算出相应运费得出最小值。也可简化计算,得出建在某一个城市的运费后可以依次推出其他可能的运费。将环形分布的城市根据距离当前酒厂的位置划分为两个区域,ld代表逆时针区域需求量,rd代表顺时针区域需求量,当酒厂从i移动到i+1后,逆时针区域城市到酒厂距离分别增加D,顺时针区域城市则减少D,所以当前运费current = current + D(ld-rd) 。每次移动后,两个区域需要重新划分。
#include<iostream>
using namespace std ;int main(){ int demand[10000], dist[10000] ; int n, i, mid=0, ld=0, rd=0 ; int current=0, half, dl=10, s=0, c=0, best ; cin >> n ; for(i=0; i<n; i++){ cin >> demand[i] >> dist[i] ; c += dist[i] ; } half = c / 2 ; for(i=1; i<n; i++){ //以第一个城市为酒厂所在地 s += dist[i-1] ; if(s<=half){ //小于周长一半,划为顺时针区域 mid = i ; dl = s ; //标记分界 current += s*demand[i] ; rd += demand[i] ; } else{ //否则划为逆时针区域 current += (c-s)*demand[i] ; ld += demand[i] ; } } best = current ; //假设当前选址为最佳选择 for(i=1; i<n; i++){ //依次枚举酒厂所在其他城市时的情况 ld += demand[i-1] ; //原酒厂所在城市移入逆时针区域 rd -= demand[i] ; //将酒厂所在城市移出顺时针区域 dl -= dist[i-1] ; current += (ld-rd)*dist[i-1] ; while(dl+dist[mid]<=half){ dl += dist[mid] ; mid = (mid+1)%n ; current -= (c-dl-dl)*demand[mid] ; ld -= demand[mid] ; rd += demand[mid] ; } if(current<best) best = current ; } cout << best << endl ; return 0 ;}