【JZOJ 4678】钱仓

来源:互联网 发布:生化危机6优化怎么样 编辑:程序博客网 时间:2024/05/16 09:28

Description

这里写图片描述

抽象题意:给出一个带权值圆环,每个操作的代价为()2,求最小的代价。

Sulution

这题很显然可以用贪心来搞,枚举每轮的开头,贪心的来选则方案,复杂度:O(n2)
优化:
我们可以发现,无论开头是谁,只要方案合法,则一定是最优的,
所以找到一组合法解后直接输出即可
复杂度:O(n)

Code

#include<iostream>#include<cstdio>#include<cstdlib>#include<cmath>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fod(i,a,b) for(int i=a;i>=b;i--)using namespace std;typedef long long LL;const int N=200500,INF=2147483640;int read(int &n){    char ch=' ';int q=0,w=1;    for(;(ch!='-')&&((ch<'0')||(ch>'9'));ch=getchar());    if(ch=='-')w=-1,ch=getchar();    for(;ch>='0' && ch<='9';ch=getchar())q=q*10+ch-48;n=q*w;return n;}LL ans;int n,m;int a[N],b[N];bool doit(int q){    fo(i,q,q+n-1)b[i-q+1]=a[i];    ans=0;    int l,r;l=r=n;    while(--l>0)    {        while(b[l])        {            b[l]--;            b[r]++;            ans+=(r-l)*(r-l);            while(b[r])            {                if(b[r]>1)return 0;                r--;            }            l=min(l,r);        }    }    fo(i,1,n)if(b[i]!=1)return 0;    printf("%lld\n",ans);    return 1;} int main(){    int q;    read(n);    fo(i,1,n)a[i+n]=read(a[i]);    q=0;    for(int i=2*n,j=2*n;i>1;i--)    {        q+=a[i]-1;        while(q>0)q-=a[j--]-1;        if(j-i+1>=n)if(doit(i))return 0;    }    return 0;}
0 0
原创粉丝点击