這好像是我第一次嘗試寫乙個新知識入門
而不是習題解
我們都知道,二分是在乙個單調函式(即一次函式)上通過每次查詢折半的方式,對答案進行搜尋查詢。那麼,三分就是在乙個單峰函式(二次函式,拋物線)上,不斷地將答案分為三份,
通過兩者的比較來求取這個峰值(極值)的答案。
對於所要求解的範圍[l,r],計算出兩個點m1和m2將整個範圍分為三段,
m1在從左數1/3處,m2在從左數2/3處。每次計算時,計算m1處和m2處的值,
在這兩個點中,更接近我們想要的答案的那個值稱為好點,另乙個稱為壞點,
並更新靠近壞點那一側的邊界值。最後直到搜尋到我們的答案為止。
也就是如果我們要找最大值,且m1>m2就三分l~m2,即把右端點r變為m2
為什麼是靠近壞點呢?以求最大值為例(凸峰函式,a<0)解釋
因為我們是三分答案,有可能出現m1,m2都在我們答案點的左邊或者右邊,
假設都在右邊,m1的值大於m2的值,如果我們靠近好點,把l變成了m1,就徹底離開了答案的懷抱!!
反之,靠近壞點,更改r,在新的[l,r]區間內仍是包含著答案點的!
換言之,我們找到了兩個點,m1優於m2,那麼[m2,r]也一定是不優於m1的,就可以大膽捨去
但我們不能保證[l,m1]全都不優於m1,無法割捨的愛
三分是與二分相似的,count就是我們對答案正確性的判斷
int count (
int x )
void sanfen (
double l,
double r )
double mid1 = l +
( r - l )
/3.0
;double mid2 = r -
( r - l )
/3.0;if
( count ( mid1 )
< count ( mid2 )
) sanfen ( l, mid2 )
;else
sanfen ( mid1, r )
;}
給定n個二次函式f1(x),f2(x),…,fn(x)(均形如ax^2+bx+c),設f(x)=max,求f(x)在區間[0,1000]上的最小值。
輸入格式
輸入第一行為正整數t,表示有t 組資料。
每組資料第一行乙個正整數n,接著n行,每行3個整數a,b,c ,用來表示每個二次函式的3個係數,
注意二次函式有可能退化成一次。
輸出格式
每組資料輸出一行,表示f(x)的在區間[0,1000]上的最小值。答案精確到小數點後四位,四捨五入。
輸入輸出樣例輸入2
12 0 0
22 0 0
2 -4 2
輸出0.0000
0.5000
說明/提示
【資料範圍】
t < 10, n ≤ 10000,0 ≤ a ≤ 100,|b| ≤ 5000, |c| ≤ 5000 前50%資料n ≤ 100
說了這道題是例題,那麼肯定是三分啦!but。。。
我竟然和仙女同學們一起討論了為什麼是三分
我們以題目要求來分析,用最簡單的兩個函式為例,如圖:
每次都要取最大值,也就意味著當至少兩個函式遇到相交點,
如果第乙個函式開始遞增,那麼就必定函式逐步遞減有一段會代替它,接上它
就根本不會出現大波浪捲髮的形狀,不能理解也沒關係,好好想想就行了!這不重要
這道題就是個模板,所以沒有什麼思維可講,唯一有點臭不要臉的就是,精度!!!
eps不能卡著四位小數開,
因為題目要的是y也就是函式結果的精度四位,而我們三分的是x,精度要更高開個1e-9就能卡過了
我被卡哭了,本仙女也不會告訴你我剛開始連題目都理解錯了~
}好了,三分就這樣啦,感覺。。。
三分演算法(曲線)
一 適用場景三分演算法適用於求解凸性函式的極值問題,二次函式就是乙個典型的單峰函式。二分利用的是函式的單調性,三分演算法利用的是函式的單峰性。在區間 l,r 令m1 l r l 3,m2 r r l 3,分別位於1 3 2 3處,接著計算這兩個點的函式值,如果f m1 f m2 求解區間有 l,r ...
二分 三分模板
適用於 單調函式 單調增或單調減 基本思想 給定9個數,由小到大排列,從這9個數中找出某乙個確切的數 比如4 偽 int binary sreach int a,int left,int right,int x if a left x return left return 1 給你三個陣列a,b,c...
(求極值)三分模板
三分求極值法 如果要求極值,二分法早就失去了他的意義了。不過還是可以用三分法來實現的,就是二分中再來二分。比如我們定義了l和r,m l r 2,mm mid r 2 如果mid靠近極值點,則r mm 否則就是mm靠近極值點,則l m 這樣的話,極值還是可以求的 include include inc...