三分~求最值

三分算法:  求凹凸函数的最值~~ 

 

图片

题意: 求影子最大长度。
 
思路:在墙面的影子为 X, 灯高H, 人高h, 灯距墙D。
      给灯和人 都减去墙面影子的长度,则为相似三角形
      三角形定理   影子长度为    (h-X)*D/(H-X) + X;
#include <cstdio>
#include <iostream>
using namespace std; #define eps 1e-9 //double 的精度差 double H, h, D; double f(double x) { return (h-x)*D/(H-x)+x; //x为影子在墙上的高度~~ } /* double sanfen(double l, double r) //三分法查找最大值 { while(r-l>eps) //无等号,否则有陷入死循环的危险 { double mid1=l+(r-l)/3.0; double mid2=r-(r-l)/3.0; if(f(mid1) <= f(mid2)) l=mid1; //这里不清楚的可以纸上画画~~ else r=mid2; } return (l+r)*0.5; } */ double sanfen(double l, double r) //另外一种三分方法~~ { while(r-l>eps) //无等号,否则有陷入死循环的危险 { double mid1=(l+r)/2.0; double mid2=(mid1+r)/2.0; if(f(mid1) <= f(mid2)) l=mid1; else r=mid2; } return (l+r)/2.0; } int main() { int t; scanf("%d", &t); while(t--) { scanf("%lf%lf%lf", &H, &h, &D); printf("%.3lf\n", f(sanfen(0, h))); } return 0; }

 

 
题目大意:有n个人,每个人都有一个位置xi以及压力值wi, 在当前位置x, 有一个糟糕值 = (x-xi)^3 * wi; 且n个人的位置xi是有序的,  求一个位置x 是的糟糕值最小。
#include <cstdio>
#include <cmath>

using namespace std;

#define eps 1e-9

double x[50005], w[50005];
int n;

double f(double a)                   //连和公式
{
    double rea=0;
    for(int i=1; i<=n; i++)
    {
        double d=a-x[i];
        if(d<0) d=d*(-1.0);
        rea+=d*d*d*w[i];
    }
    return rea;
}

double sanfen(double l, double r)     //三分求最小值所在位置
{
    while(r-l>eps)
    {
        double mid1=l+(r-l)/3.0;
        double mid2=r-(r-l)/3.0;
        if(f(mid1) > f(mid2)) l=mid1;
        else r=mid2;
    }
    return (l+r)/2.0;
}

int main()
{
    int t, ti, i;
    scanf("%d", &t);
    for(ti=1; ti<=t; ti++)
    {
        scanf("%d", &n);
        for(i=1; i<=n; i++)
            scanf("%lf%lf", &x[i], &w[i]);
        double s=f(sanfen(x[1], x[n]));
        printf("Case #%d: %d\n", ti, (int) (s+0.5) );   //这是四舍五入的技巧~~
    }
    return 0;
}

 

posted @ 2015-09-22 17:05  马晨  阅读(101)  评论(0)    收藏  举报