如題,給出一個\(N\)次函數,保證在範圍\([l,r]\)內存在一點\(x\),使得\([l,x]\)上單調增,\([x,r]\)上單調減。試求出\(x\)的值。函數
輸入格式:學習
第一行一次包含一個正整數\(N\)和兩個實數\(l、r\),含義如題目描述所示。spa
第二行包含\(N+1\)個實數,從高到低依次表示該\(N\)次函數各項的係數。code
輸出格式:blog
輸出爲一行,包含一個實數,即爲\(x\)的值。四捨五入保留\(5\)位小數。ip
輸入樣例#1:內存
3 -0.9981 0.5 1 -3 -3 1
輸出樣例#1:it
-0.41421
時空限制:\(50ms,128M\)io
數據規模:模板
對於\(100\%\)的數據:\(7<=N<=13\)
樣例說明:
如圖所示,紅色段即爲該函數\(f(x)=x^3-3x^2-3x+1\)在區間\([-0.9981,0.5]\)上的圖像。
當\(x=-0.41421\)時圖像位於最高點,故此時函數在\([l,x]\)上單調增,\([x,r]\)上單調減,故\(x=-0.41421\),輸出\(-0.41421\)。
(Tip.l&r\(的範圍並非很是大\)ww$不會超過一位數)
思路:其實以前作過這個題目,可是用的不是三分法,因此今天看知識體系,恰好發現本身不會三分法,就去學習了一下順便回顧了這道模板題,三分的思路就是,先取\(l\)和\(r\)的中間點\(mid\),再取\(mid\)和\(r\)的中間值\(mmid\),而後比較\(f(mid)\)和\(f(mmid)\),其中\(f(x)\)表示把x代入函數後的值爲多少,若是\(f(mid)>f(mmid)\),說明要找的點在\(mmid\)的左邊,因此就讓\(r=mmid\),繼續三分,反之,讓\(l=mid\),繼續三分,最後的\(l\)和\(r\)必定會愈來愈接近要找的點,r和l的差在偏差容許範圍內時,就找完了。
代碼:
#include<cstdio> #include<algorithm> #define dl double #define maxn 15 using namespace std; const dl eps=1e-7; int n; dl a[maxn],l,r,p; inline dl js(dl x) { dl res=a[0]; for(int i=1;i<=n;++i) { dl tmp=a[i]; for(int j=1;j<=i;++j) tmp*=x; res+=tmp; } return res; } int main() { scanf("%d%lf%lf",&n,&l,&r); for(int i=n;i>=0;--i) { scanf("%lf",&p); a[i]=p; } while(l+eps<r) { dl mid=(l+r)/2; dl mmid=(mid+r)/2; if(js(mid)>js(mmid)) r=mmid; else l=mid; } dl ans=js(l)>js(r)?l:r; printf("%0.5lf\n",r); return 0; }