【NOIP2016提高A组8.11】钱仓
题目
分析
发现,一定有一个点作为起点,所有的路径都不经过这个起点。
接着贪心求答案,
如果\(c_i>1\),将其中\(c_i-1\)个钱往后“铺”。
易证\(x^2+y^2<=(x+y)^2\)
那么维护一个队列,先进先出,就能保证最小。
#include <cmath>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
const int maxlongint=2147483647;
const int mo=1000000007;
const int N=150005;
using namespace std;
int d[N],c[N*2],n,m,tot,mak[N];
long long ans;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&c[i]);
c[i+n]=c[i];
}
for(int i=1;i<=n;i++)
{
tot=ans=0;
int sum=0,head=1;
for(int j=1;j<=n;j++)
{
mak[j]=c[i+j-1];
sum+=mak[j];
if(sum<j)
{
ans=-1;
break;
}
}
if(ans>=0)
for(int j=1;j<=n;j++)
{
while(mak[j]--)
{
d[++tot]=j;
}
mak[j]++;
ans+=(j-d[head])*(j-d[head]);
head++;
}
if(ans>=0)
{
printf("%lld",ans);
return 0;
}
}
}