LA4986三分法求出凹性函数最小值+计算几何

 1 /*LA4986
 2 三分法求出凹性函数最小值:
 3 三分法本身的写法不难,这道题的关键是数学:
 4 1、找到表示量h,找到r与h的唯一确定关系,进而确定了h,就确定了相应的v
 5 2、判断出v(h)是一个凹性函数。因为r受离散的点的影响,无法从列函数,确定凹性。
 6 我也仅仅是从极限的思想上考虑的。当h无限小,由(0,0,h)连向点p的直线越平,r趋向于无穷;
 7 当h无限大时,r的增长速度更不上h,h趋向于无穷。
 8 3、故v(h)的两边是无限增大的
 9 */
10 #include<iostream>
11 #include<stdio.h>
12 #include<string.h>
13 #include<algorithm>
14 #include<stdlib.h>
15 #include<math.h>
16 #include<queue>
17 #include<vector>
18 #include<map>
19 #define LL long long
20 
21 using namespace std;
22 
23 int n;
24 double a[10005],b[10005],c[10005],minH;
25 
26 double GetR(double H)
27 {
28     double mr=sqrt(a[1]*a[1]+b[1]*b[1])*H/(H-c[1]);
29     for(int i=2;i<=n;i++)
30     mr=max(mr,sqrt(a[i]*a[i]+b[i]*b[i])*H/(H-c[i]));
31     return mr;
32 }
33 double F(double H)//返回的是由h确定的r,进而确定的V
34 {
35     double mr=GetR(H);
36     return M_PI/3*mr*mr*H;
37 }
38 void solve()
39 {
40     double L=minH,R=10000000;
41     while(L+1e-7<R)
42     {
43         double m1=L+(R-L)/3;
44         double m2=R-(R-L)/3;
45         double Fm1,Fm2;
46         Fm1=F(m1);Fm2=F(m2);
47 //        cout<<"L="<<L<<","<<"R="<<R<<endl;
48         if (Fm1<=Fm2) R=m2;else L=m1;
49     }
50     printf("%.3lf %.3lf\n",L,GetR(L));
51 
52 }
53 int main()
54 {
55     while(cin>>n)
56     {
57         minH=1e-8;
58         for(int i=1;i<=n;i++) {
59             cin>>a[i]>>b[i]>>c[i];
60             minH=max(minH,c[i]);
61         }
62         solve();
63     }
64     return 0;
65 }

 

posted @ 2014-02-26 20:56  little_w  阅读(555)  评论(0编辑  收藏  举报