zoukankan      html  css  js  c++  java
  • 三分,你比二分多一分

    三分应用于最优化问题的求解。在解题时没必要给出证明,只要知道问题不满足单调性,就可以尝试用三分搜索极值点,而且三分整数很少见,因为除非能够证明这种策略是正确的(即完全符合凸函数的性质,但是通常极值点不会在整点取得,如果三分整数,那么函数也不是连续的了),否则很可能会错误,而三分应用在小数中是最常见的,比如说三分角度,三分坐标等等。

    这句话里面重点是什么呢?问题不满足单调性!极值点!

    如:

    但我觉得三分相比二分最精髓的是什么呢?

    有了互相比较的值!

    我们来想一下,二分通常是怎么写的,是不是 if (mid<答案)then  { left or right=mid  }

    但是如果题目就叫你求这个答案呢?三分就很有用处了。

    对于一组数据,如果它有极值点,我们就用三分。

    具体怎么实现,就是我的当前左答案小于or大于右答案,然后 left or right=mid ,逐步逼近极值点。

    我们来一道例题

    https://nanti.jisuanke.com/t/43512

    很明显这题是有极值点,且只有一个,不懂怎么证明的话可以像我一样,写一个暴力程序,一个一个枚举,看枚举出来的每个值要移动多少步才符合要求,然后你就发现数据是递减后递增的。

    一开始我只知道二分,所以很显而易见的做不出来,贪心又不会贪,最终只能送人头。

    这题三分的做法,就是三分第一个啤酒摊的坐标,然后左边右边进行比较,之后就是常规三分做法

    #include <bits/stdc++.h>
    #define INF 0x3f3f3f3f3f3f3f3f
    typedef long long ll;
    int a[1000005],i,n,m;
    ll l,r,mid1,mid2,ans1,ans2,ans;
    using namespace std;
    ll solve(ll x)
    {
        ll ans=0;
        for (int i=1;i<=n;i++)
        {
            ans+=abs(a[i]-x);
            x+=m;
        }
        return ans;
    }
    int main()
    {
        while (~scanf("%d%d",&n,&m))
        {
        for (i=1;i<=n;i++)    scanf("%d",&a[i]);
        sort(a+1,a+1+n);
        l=-1e12;
        r=1e12;
        ans=INF;
        for (i=1;i<=100;i++)
        {
            mid1=l+(r-l)/3;
            mid2=r-(r-l)/3;
            ans1=solve(mid1);
            ans2=solve(mid2);
            if (ans1>ans2) l=mid1;
                else r=mid2;
            ans=min(ans,min(ans1,ans2));
        }
        cout<<ans<<endl;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Java Project和Web Project 区别
    ScannerTest-------double string
    ScannerDemo------string int
    clearfix 清除浮动的标签
    bootstrap 的布局
    <span>元素
    反省
    Django中ifequal 和ifnotequal的使用
    IndexError: list index out of range的错误原因
    python2和python3同时存在电脑时,安装包时的的命令行
  • 原文地址:https://www.cnblogs.com/Y-Knightqin/p/12369795.html
Copyright © 2011-2022 走看看