HNOI2002 彩票 搜尋

2022-04-30 11:45:07 字數 1294 閱讀 9205

某地發行一套彩票。彩票上寫有1到m這m個自然數。彩民可以在這m個數中任意選取n個不同的數打圈。每個彩民只能買一張彩票,不同的彩民的彩票上的選擇不同。

每次**將抽出兩個自然數x和y。如果某人拿到的彩票上,所選n個自然數的倒數和,恰好等於x/y,則他將獲得乙個紀念品。

已知**結果x和y。現在的問題是,必須準備多少紀念品,才能保證支付所有獲獎者的獎品。

輸入格式:

輸入檔案有且僅有一行,就是用空格分開的四個整數n,m,x,y。

輸出格式:

輸出檔案有且僅有一行,即所需準備的紀念品數量。

1≤x, y≤100,1≤n≤10,1≤m≤50。

輸入資料保證輸出結果不超過10^5。

輸入樣例#1:

2 4 3 4

輸出樣例#1:

本來是本著刷splay的心去刷這道題的,結果一看題目感覺是搜尋,點開演算法標籤\(splay\)????

再點開討論和題解(發現並沒有人用splay做)看了一下應該是有人惡搞(人才.....)

回到這道題,首先直接爆搜肯定是不行的,題目所給的m有50,最壞時間複雜度應該有\(o((m-1)!)\).顯然過不了,馬上想到剪枝,這個剪枝應該還是比較容易想到的

如果當前結果\(tot\)>\(x/y\),返回

如果當前結果\(tot\)+後續能加的最大值<\(x/y\),返回

如果當前結果\(tot\)+後續能加的最小值》\(x/y\),返回

用個字首和優化一下就可以了

就這三個最優性剪枝就已經能a掉這道題了,注意一下,陣列比題目所給的50開大點,我也不知道為什麼開60只有70分(t三個點),開70a了,開100又比開70快300ms

#include#define in(i) (i=read())

using namespace std;

int read()

while(i>='0' && i<='9')

return ans*f;

}int n,m,x,y,ans;

double sta,eps=1e-10;

int vis[100];

double sum[100];

void dfs(int x,int last,double tot)

for(int i=last+1;i<=m;i++)

}}int main()

HNOI2002 營業額統計

花了一天鑽研了splay,然後發現splay沒我想象的那麼難 以前都是寫sbt來著 但是splay的速度確實沒那麼快,但是真的挺好寫的 我寫的版本測了這題以後又用了一下別人的splay,發現通過這題大多數splay在750ms上下,我是688ms,說明還算是不錯的啦 啦啦啦 include incl...

HNOI 2002 營業額統計

最近開始重新學習splay樹寫的第一題,基本就是照著別人部落格改的一道題,關於splay樹的模板,感覺大牛已經把 改得很短!這道題沒什麼難度,乙個插入操作,乙個找前驅,乙個找後驅的操作。話說這題有個資料有個bug的地方,可以看連線的discuss 因為沒有push down,push up的操作,感...

HNOI2002 營業額統計

傳送門 題目大意 求一段序列,小於當前元素的最大值和大於當前元素的最小值。從該元素前面的元素找。題解 建立線段樹維護或者使用雙向鍊錶.或stl水過 線段樹每次插入乙個新值,查詢大於它的最小值和小於它的最大值 雙向鍊錶有點神.我們知道排序後乙個數的前驅就是小於它的最大值 後繼就是大於它的最小值,我們將...