zoukankan      html  css  js  c++  java
  • HDU 4355 Party All the Time (三分求极值)

    题意:给定x轴上有n个点,每一个点都有一个权值,让在x轴上选一个点,求出各点到这个点的距离的三次方乘以权值最小。

    析:首先一开始我根本不会三分,也并没有看出来这是一个三分的题目的,学长说这是一个三分的题,我就百度了一下什么是三分算法,一看感觉和二分差不多,当然就是和二分差不多,也是慢慢缩短范围。

    这个题也这样,在最左端和最右端不断的三分,直到逼进那个点,刚开始我设置的误差eps是10负8,但是TLE了,我以为是太小,三分数太多,然后我又改成10负6还是TLE,我又失望了,干脆我不用误差了,我让它三分200次就结束,但一直是TLE,直到我改到20次,才AC。但实际并不是我设置的太小,而是我用了pow这个函数和fabs这个函数,这两个函数运行起来太慢了,导致我TLEn次,所以我不建议用这两个函数,完全可以自己写嘛,这样才会更快。

    知道三分,这个题就很简单了,就是扫一下而已。

    代码如下:

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <set>
    #include <map>
    #include <cmath>
    #include <string>
    #include <vector>
    
    using namespace std;
    typedef long long LL;
    const int maxn = 50005;
    const double eps = 1E-6;
    double x[maxn], w[maxn];
    int n;
    
    double f(double mid){
        double ans = 0.0;
        for(int i = 0; i < n; ++i)
            ans += pow(fabs(x[i] - mid), 3) * w[i];
        return ans;
    
    }
    int main(){
        int T, cases = 0;  cin >> T;
        while(T--){
            scanf("%d", &n);
            for(int i = 0; i < n; ++i)
                scanf("%lf %lf", &x[i], &w[i]);
    
            double r = x[n-1], l = x[0];
            for(int i = 0; i < 30; ++i){
                double mid_l = l + (r-l) / 3.0;
                double mid_r = r - (r-l) / 3.0;
                if(f(mid_l) < f(mid_r))  r = mid_r;
                else l = mid_l;
            }
    
            int ans1 = (int)floor(f(l)+0.5), ans2 = (int)floor(f(r)+0.5);
            int ans = min(ans1, ans2);
            printf("Case #%d: %d
    ", ++cases, ans);
        }
        return 0;
    }
    

    这是我不用pow函数的代码:

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <set>
    #include <map>
    #include <cmath>
    #include <string>
    #include <vector>
    
    using namespace std;
    typedef long long LL;
    const int maxn = 50005;
    const double eps = 1E-8;
    double x[maxn], w[maxn];
    int n;
    
    double f(double mid){
        double ans = 0.0;
        for(int i = 0; i < n; ++i){
            double tmp = x[i] - mid;
            if (tmp < 0)tmp = -tmp;
            ans += tmp*tmp*tmp* w[i];
    
        }
        return ans;
    
    }
    int main(){
        int T, cases = 0;  cin >> T;
        while(T--){
            scanf("%d", &n);
            for(int i = 0; i < n; ++i)
                scanf("%lf %lf", &x[i], &w[i]);
    
            double r = x[n-1], l = x[0];
            while(r - l > eps){
                double mid_l = l + (r-l) / 3.0;
                double mid_r = r - (r-l) / 3.0;
                if(f(mid_l) < f(mid_r))  r = mid_r;
                else l = mid_l;
            }
    
            int ans1 = (int)floor(f(l)+0.5), ans2 = (int)floor(f(r)+0.5);
            int ans = min(ans1, ans2);
            printf("Case #%d: %d
    ", ++cases, ans);
        }
        return 0;
    }
    
  • 相关阅读:
    安卓iOS软件免编程开发步骤
    我的站被收录了两次,被封掉两次,怎么办?
    百度算法调整 优化网站该从哪几方面着手?
    如何成为php编程高手
    百度等搜索引擎寻找各种数据库网站的方法
    【网站抓取】如何正确识别Baiduspider移动ua
    EditPlus 技巧大全:[1]怎么配置PHP编译环境
    如何本地搭建php环境用来测试PHP程序教程!
    用最简洁的代码构建MVC分层
    BMR计算器2——python第三课(字符串分割,格式化输出,异常处理)
  • 原文地址:https://www.cnblogs.com/dwtfukgv/p/5528785.html
Copyright © 2011-2022 走看看