正题
题目链接:https://jzoj.net/senior/#main/show/3832
题目大意
一个环形的,知道每个城市分布的位置和需要的酒数。然后要求在一个位置建厂使得运输价格最低。
解题思路
我们将数据复制一份放到后面,然后枚举建厂位置。我们现在要找到一个包含该位置的长度为nnn的区间使得价格最低。我们发现当建厂位置往右边移动时,区间的位置不会向左,所以我们可以用指针维护即可。
时间复杂度O(n)O(n)O(n)
codecodecode
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll N=41000;
ll n,w[N],d[N],x[N],lw,rw,ans,maxs=1e18;
int main()
{//freopen("bro.in","r",stdin);//freopen("bro.out","w",stdout);scanf("%lld",&n);for(ll i=1;i<=n;i++){scanf("%lld%lld",&w[i],&d[i]);x[i]=x[i-1]+d[i-1];rw+=w[i];ans+=w[i]*x[i];w[i+n]=w[i];d[i+n]=d[i];}for(ll i=n+1;i<=2*n;i++)x[i]=x[i-1]+d[i-1];ll l=1,r=n+1;for(ll i=1;i<=2*n;i++){lw+=w[i-1];rw-=w[i];ans+=lw*d[i-1]-rw*d[i-1]-w[i]*d[i-1];while(r<=2*n&&(x[i]-x[l])*w[l]>=(x[r]-x[i])*w[r])ans+=(x[r]-x[i])*w[r]-(x[i]-x[l])*w[l],lw-=w[l++],rw+=w[r++];maxs=min(maxs,ans);}printf("%lld",maxs);
}