P3382 【模板】三分法
阿新 • • 發佈:2022-02-19
題目
如題,給出一個 \(N\) 次函式,保證在範圍 \([l, r]\) 記憶體在一點 \(x\),使得 \([l, x]\) 上單調增,\([x, r]\) 上單調減。試求出 \(x\) 的值。
思路
本題可以用導數做,(逃
首先,一個 \(N\) 次函式無非就是 一個這樣的函式:
\[f(x)=\sum_{i=0}^{n} a_{i}x^{i} \]而根據導數加法法則可以知道,加法函式滿足這樣的一個性質:
\[(f(x)+g(x)+h(x)+i(x)+...)^{'} = (f^{'}(x)+g^{'}(x)+h^{'}(x)+i^{'}(x)+...) \]因此我們就把他轉換成一個求 \(a_{i}x^{i}\)
注意常數的導數為0.
而計算可知,\((a_{i}x^{i})^{'}=a_iix^{i-1}\),所以多項式的函式就變成了
\[f^{'}(x)=\sum_{i=1}^{n} a_iix^{i-1} \]話說為什麼要用導數呢?
應為導數的性質告訴我們,一個函式如果區間遞增那麼導數值要大於等於0!反之就是小於等於0!
可以二分了!
注意,可能會有浮點數誤差!
程式碼
#include <bits/stdc++.h> #define int double using namespace std; int n,l,r,a[15]; int eps=1e-10,mid; int derivative(int x){ int result=0; for(signed i=1;i<=n;i++){ result+=a[i]*i*pow(x,i-1); } return result; } signed main(){ cin>>n>>l>>r; for(signed i=n;i>=0;i--){ cin>>a[i]; } while(r-l>eps){ mid=(l+r)/2; if(derivative(mid)>0){ l=mid; } else{ r=mid; } } printf("%.5lf",mid); return 0; }