我的思考 最小函式值

2022-05-07 21:39:08 字數 2085 閱讀 4396

該題目給定了我們一些二次函式,不過這個函式只取了橫座標為正整數部分的值,並且三個係數都為正數,通過代數證明或者影象對稱軸分析,都可以肯定,該函式在其定義域(正整數)上,單調遞增且恆大於0。

接下來我們再看到題目要求,求這些函式所生成的所有函式值中最小的m個。

比較暴力的方法是從1開始迴圈(可能不是最暴力的方法),將1代入所有的函式中,分別得到n個函式值,然後再迴圈到2,按照這樣的方法再來一遍,又有n個函式值,又因為這些都是在其定義域內單調遞增的函式,那麼首先可以確定1中所有小於等於2中最小函式值的函式值,然後接著按照上述方案做,迴圈到k時,可以確定從x=1到x=k-1中所有小於等於x=k中最小函式值的函式值,直到確定了m個值。

但是這樣的話,思想實在簡單,絕配暴力演算法一名。暴力之處在於:一、每次求出\(o(n)\)的函式值,耗費\(o(n)\)的空間,最壞情況下要求\(o(mn)\)次,花費\(o(mn)\)空間,而資料一大,時間空間無疑是要超出範圍的;二、每次迴圈求出的函式值得進行排序,如果不排序,那個運算量不敢恭維,假設使用\(\theta (nlgn)\)複雜度排序,那麼也需要花\(\theta (mnlgn)\)的複雜度;三、再加上每次需要計算x=k中的最小函式值與前面k-1中所有的函式值進行比較,這樣在最壞情況下時間代價為:

\[o(\sum _ ^ (kn))=o((m-1)mn/2)=o(m^2n)

\]那麼,總的算來,就會消耗\(o(o(mn)+\theta (mnlgn)+o(m^2n))=o(m^2n)\)的時間代價,極其暴力!而且空間上的消耗也是巨大的

那麼,我們該如何優化呢?

其實,大家看到函式解析式極其定義域就不難知道,他實際上是給了我們n串排好序的陣列,只是每個陣列中下標與其值存在一定的對應關係。我們由上面所說的可知,對於每個陣列,它們的最小值所在的下標都是1。現在,我們可以想象一下,每個陣列都有乙個箭頭,每個箭頭都指向1,然後在所有箭頭指向的函式值中,找到最小的那個,此時已經找到了1個最小函式值。接著,剛才輸出來的值所對應的箭頭就要向後移,指向x=2,然後再去和其他箭頭指向的函式值比較,以此類推。下面的兩個圖形象地展現了一部分操作過程。

那麼,現在我們需要將文字描述轉化為程式思路。

首先我們需要用三個陣列存a、b、c的值,然後需要乙個cmin存當前最小值,最後只需要拿乙個陣列f來表示每個函式中的那個「箭頭」所指的位置,那麼箭頭所指的函式值就會是\(a[k]f[k]^2+b[k]f[k]+c[k]\),至此,思路就很明了了。

下面是我寫的程式,很簡單,最長耗時測試點用了344ms,沒超時。

#include using namespace std;

int main()

for(i=0;i該程式的時間複雜度為\(\theta (mn)\)。

大家也許會發現,這裡每次都重複計算了很多函式的值,浪費了很多時間,那有沒有辦法針對這一問題進行優化呢?答案是肯定的。

對於上述問題的優化方法,比較好的是用堆來做。思路是這樣的:首先,我們可以在所有「箭頭」指向1的時候,對所有箭頭對應的函式值建立小根堆;然後,每次從堆頂取走那個數,並將其所對應的「箭頭」指向下乙個函式值,然後把這個新的函式值代替那個取走的函式值放在堆頂,並自頂向下維護堆(大家可以證明一下,一直這樣操作下去,堆的性質恆成立)。下面是我的參考程式:

#include using namespace std;

struct dui

a[10010];

int heap_size;//堆的大小

void change(int m, int n)//自己寫的交換函式

void min_heapify(int i)

int main()

heap_size=n;

build_heap();

for(i=0; i該程式的時間複雜度為\(\theta (nlgn)\)或\(\theta (mlgn)\)。程式在洛谷上測試通過了,並且最大耗時的測試點耗時8ms。

最小函式值

給n個函式。fi x ai x 2 bi x ci 給定這些ai bi和ci,請求出所有函式的所有函式值中最小的m個。3 10 4 5 3 3 4 5 1 7 1 9 12 12 19 25 29 31 44 45 54 維護乙個小根堆,裡面的值為,按照要求每次輸出堆頂,並將堆頂函式中的x加1再下調...

最小函式值

最小函式值 time limit 1000ms memory limit 65536k total submit 121 accepted 54 description 問題描述 有n個函式,分別為f1,f2,fn。定義fi x ai x 2 bi x ci x n 給定這些ai bi和ci,請求出...

最小函式值

題目描述 有n個函式,分別為f1,f2,fn。定義fi x aix 2 bix ci x n 給定這些ai bi和ci,請求出所有函式的所有函式值中最小的m個 如有重複的要輸出多個 輸入格式 輸入資料 第一行輸入兩個正整數n和m。以下n行每行三個正整數,其中第i行的三個數分別位ai bi和ci。ai...