OJ2360斜率优化

Posted farway17

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OJ2360斜率优化相关的知识,希望对你有一定的参考价值。

题意 :

给定一个长度为 (n) 的数列 (a_i) ,定义函数 (f(i,j)=(i-j)^2+g^2(i,j)(1le i< jle n)) ,其中 (g(i,j)=sum_{k=i+1}^j a_k) .

(min{ f(i,j) }) .

题解:

将上面的式子定义为平面上两点距离,即为求最近点对距离。

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
namespace io {
    const int SIZE=(1<<21)+1;
    char ibuf[SIZE],*iS,*iT,c;
    #define gc()(iS==iT?(iT=(iS=ibuf)+fread(ibuf,1,SIZE,stdin),(iS==iT?EOF:*iS++)):*iS++)
    template <class I>
    inline void gi (I &x){
        for(c=gc();c<'0'||c>'9';c=gc());
        for(x=0;c<='9'&&c>='0';c=gc()) x=(x<<1)+(x<<3)+(c&15);
    }
}
using io::gi;
const int N=200005;
struct node {
    int x,y;
} a[N];
bool operator < (node s, node t) {
    return s.x<t.x;
} int n,s[N];
double dis(node s, node t) {
    return sqrt(1ll*(s.x-t.x)*(s.x-t.x)+1ll*(s.y-t.y)*(s.y-t.y));
}
bool cmp(int s, int t) {
    return a[s].y<a[t].y;
}
double solve(int l, int r)
{
    if(r-l==1) return dis(a[l],a[r]);
    if(r-l==2) return min(dis(a[l],a[r]),min(dis(a[l],a[l+1]),dis(a[l+1],a[r])));
    int mid=l+r>>1,id=0;
    double mn=min(solve(l,mid),solve(mid+1,r));
    for(int i=mid;i>=l&&a[mid].x-a[i].x<=mn;--i) s[++id]=i;
    for(int i=mid+1;i<=r&&a[i].x-a[mid+1].x<=mn;++i) s[++id]=i;
    sort(s+1,s+1+id,cmp);
    for(int i=1;i<=id;++i)
        for(int j=i+1;j<=id&&a[s[j]].y-a[s[i]].y<=mn;++j) mn=min(mn,dis(a[s[i]],a[s[j]]));
    return mn;
}
int main()
{
#ifndef ONLINE_JUDGE
    freopen("3473.in","r",stdin);
#endif
    gi(n);
    for(int i=1;i<=n;++i) gi(a[i].x),gi(a[i].y);
    sort(a+1,a+1+n);
    printf("%.4lf",solve(1,n));
}

以上是关于OJ2360斜率优化的主要内容,如果未能解决你的问题,请参考以下文章

斜率优化系列——训练记录

HDU 3507 Print Article(斜率优化)

UVALive 4726 Average ——(斜率优化DP)

3156: 防御准备(斜率优化)

hdu 3480 Division(斜率优化)

hdu 3507 Print Article(斜率优化)