三分~求最值
三分算法: 求凹凸函数的最值~~
题意: 求影子最大长度。
思路:在墙面的影子为 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; }

浙公网安备 33010602011771号