zoukankan      html  css  js  c++  java
  • 一本通 高手训练 1788 爬山 dp 斜率 凸包

    LINK:爬山

    很早以前看的题目 发现自己想的完全不对 这道题还是比较有价值的。

    先不考虑走的路线问题 考虑某个点能看到的最高的山。

    分左边和右边来考虑 考虑左边 利用单调栈存长度单调递减的山 不能直接取最高的 因为最高的山可能被遮住了。

    然后分析到底哪座山可以取 设当前点为i 对于一个点k来说 如果存在j<k 且 j,k,i连线是一个下凸包那么k就没用了。

    容易发现如果把这些下凸包删掉 就是一个上凸包了 取凸包上和i相邻的点即可。

    至此 得到一个通解左边形成的凸包离i最近的点 右边同理。

    接下来考虑 如何求答案 暴力模拟可能复杂度很高 因为从一座山走到另一座山的途中路线可能会被修改。

    容易从中发现 当前点会到达某个点 某个点会继续走下去 此时高度比原来大。

    显然 这种顺序不存在环 所以只要找到这样的顺序就可以快速得到答案了。

    进一步的可以发现 每个点都会到达最高的那个点 所以这些关系形成了一棵树。

    只要建出来树就可以线性得到答案了。或者不需要建立树 直接每次到达那个关键点采用记忆化搜索即可。

    考虑对于某个点的关键点 离自己最远的那个点显然有可能是关键点。

    要么就是在路径上的点是关键点。注意开long long.

    const int MAXN=500010;
    int n,top;
    struct wy
    {
    	int x,y;
    }t[MAXN];
    ll f[MAXN];int vis[MAXN];
    int mx[MAXN],s[MAXN],fa[MAXN];
    inline int pd(int i,int j,int k)
    {
    	return (ll)(y(i)-y(j))*(x(j)-x(k))<(ll)(y(j)-y(k))*(x(i)-x(j));
    }
    inline ll dfs(int x)
    {
    	if(vis[x])return f[x];
    	vis[x]=1;
    	if(!fa[x])return f[x];
    	return f[x]=dfs(fa[x])+abs(x-fa[x]);
    }
    int main()
    {
    	freopen("1.in","r",stdin);
    	get(n);y(0)=-1;
    	rep(1,n,i)get(x(i)),get(y(i));
    	rep(1,n,i)
    	{
    		while(top>1&&pd(s[top-1],s[top],i))--top;//形成下凸包.
    		mx[i]=s[top];s[++top]=i;
    	}
    	top=0;
    	fep(n,1,i)
    	{
    		while(top>1&&pd(i,s[top],s[top-1]))--top;
    		mx[i]=y(s[top])>=y(mx[i])?s[top]:mx[i];s[++top]=i;
    	}
    	fep(n,1,i)if(y(mx[i])<=y(i)){mx[i]=i;break;}
    	top=0;
    	rep(1,n,i)
    	{
    		while(top&&(y(mx[i])>y(mx[s[top]])||(y(mx[i])==y(mx[s[top]])&&x(mx[i])>x(mx[s[top]]))))--top;
    		if(mx[i]<i)fa[i]=s[top];s[++top]=i;
    	}
    	top=0;
    	fep(n,1,i)
    	{
    		while(top&&(y(mx[i])>y(mx[s[top]])||(y(mx[i])==y(mx[s[top]])&&x(mx[i])>x(mx[s[top]]))))--top;
    		if(mx[i]>i)fa[i]=s[top];s[++top]=i;
    	}
    	rep(1,n,i)dfs(i),putl(f[i]);
    	return 0;
    }
    
  • 相关阅读:
    [leetcode]259. 3Sum Smaller 三数之和小于目标值
    题型总结之K Sum
    [Leetcode]167. Two Sum II
    题型总结之Sliding Window
    [Leetcode]703. Kth Largest Element in a Stream 数据流中的第 K 大元素
    [Leetcode]307. Range Sum Query
    pycharm同一目录下无法import明明已经存在的.py文件
    python高级特性:迭代器与生成器
    self的含义,为什么类调用方法时需要传参数?
    git三:远程仓库GitHub
  • 原文地址:https://www.cnblogs.com/chdy/p/13127375.html
Copyright © 2011-2022 走看看