zoukankan      html  css  js  c++  java
  • uoj#244. 【UER #7】短路

    题目

    orz myy

    这个矩形对称的性质非常优美,所以我们只需要考虑一个(frac{1}{4})的矩阵,即一个倒三角形

    现在我们要求的是从((1,1))到三角形对边上每个点的最短路,不难发现如果一个某一行不是前缀最小值那么一定不可能成为最优答案,我们可以直接从上面一行跑掉而不走这一行

    于是我们的路径就是一些(L)形拼了起来,对于非前缀最小行我们只可能经过上面的一个点;正确性比较好理解,我们可以通过在上一个前缀最小行多经过一些点来代替

    所以我们的策略肯定是在一个前缀最小行往右边走,直到恰好能到达下一个前缀最小行的时候再向下走,于是每一个前缀最小行经过的点数是于下一个前缀最小行之间的距离,而中间的非前缀最小行都只会被经过一次

    代码

    #include<bits/stdc++.h>
    #define re register
    #define LL long long
    #define min(a,b) ((a)<(b)?(a):(b))
    inline int read() {
    	char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
    	while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
    }
    const int maxn=1e5+5;
    int a[maxn],n,st[maxn],top;LL ans,nw,sum;
    inline int calc(int x) {return 2ll*n-1-2ll*(n-x)-1;}
    int main() {
    	n=read()+1;for(re int i=1;i<=n;i++) a[i]=read();
    	ans=1ll*a[n]*(4ll*(n-1)-3);st[top=1]=n;sum=a[n]+a[n];
    	for(re int i=n-1;i;i--) {
    		sum+=a[i]+a[i];if(a[i]>=a[st[top]]) continue;
    		nw+=2ll*(st[top]-i)*a[st[top]];
    		ans=min(ans,nw+sum+2ll*a[i]*calc(i)-a[i]);
    		st[++top]=i;
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    C# 之 获取文件名及拓展名
    C# 之 日常积累(二)
    C# 之 OpenFileDialog的使用
    Linux系统中,main函数的执行过程
    linux线程的实现
    linux内核--进程与线程
    内核线程和进程的区别
    软中断和硬中断
    Linux 2.4.x内核软中断机制
    几种USB控制器类型:OHCI,UHCI,EHCI,xHCI
  • 原文地址:https://www.cnblogs.com/asuldb/p/11826433.html
Copyright © 2011-2022 走看看