UOJ244 短路 贪心

时间:2022-12-07 19:40:17

正解:贪心

解题报告:

传送门!

贪心真的都是些神仙题,,,以我的脑子可能是不存在自己想出解这种事情了QAQ

然后直接港这道题解法趴,,,

首先因为这个是对称的,所以显然的是可以画一条斜右上的对角线,路径一定是关于这条对角线对称的,欧克然后就成功简化了点儿题目

然后就思考运动轨迹应该是什么样儿的?就可以发现,肯定是走到一层,然后沿着这一层的边框走到对角线处

这个很好解释嘛,如果你走到这一层,又回到外面那一层继续走,前面的代价都是一样的,可以考虑直接比较分叉那儿,如果内部那一层大一些,可以不走那一层,就根本没必要到那层的边框上去,如果内部那一层小一些,肯定就沿着边框走了鸭

所以可以得到路径一定是从起点到某层的左上角那个顶点,然后沿着那一层的边框一路走到对角线,然后再复制一遍就好

然后就只要能快速计算出到每层的左上角的最小代价就好

显然每一层至少要经过一个点,走了i步,然后剩下的就还要走i步,考虑怎么分配这i步是最赚的

那不就显然前缀最小值,因为当前层可达的点一定能通过前缀最小值那一层达到(因为大一些

好像解释得不太清楚,不管了就这样儿,具体可以看代码,简单明了又很短

over

哦注意一下答案可能很大,所以赋初值的时候要开大点儿,然后要开ll,亲测设inf=1e12只有10pts,,,QAQ

#include<bits/stdc++.h>
using namespace std;
#define il inline
#define ll long long
#define gc getchar()
#define ri register int
#define rc register char
#define rb register bool
#define rp(i,x,y) for(ri i=x;i<=y;++i) const int N=1e5+;const ll inf=1e18;
ll n,a[N],as,pos,ret; il ll read()
{
rc ch=gc;ll x=;rb y=;
while(ch!='-' && (ch>'' || ch<''))ch=gc;
if(ch=='-')ch=gc,y=;
while(ch>='' && ch<='')x=(x<<)+(x<<)+(ch^''),ch=gc;
return y?x:-x;
} int main()
{
n=read()+;rp(i,,n)a[n-i+]=read();as=inf;
rp(i,,n){ret+=a[i]+a[pos];if(a[i]<a[pos] || !pos)pos=i;as=min(as,*ret+1ll*a[i]*(*(n-i)-));}
printf("%lld\n",as);
return ;
}