第三次集訓——2011年3月5、6日

       今天上午講的是搜索,主要講的是搜索的順序,提出了“制約力”的概念,把它按照從大到小的順序搜索,例題有八數碼問題、質數方陣。在圖論方面主要講了SPFA,竟然是中國西安交大的教授提出來的,不簡單啊!

      中午去了龔秋成的生日宴會,在伊典。喫完後後看是上演奶油大戰……衣服則成了犧牲品。

      下午到時已遲到一個小時,所以趕緊做。下午的題目質量比較高,都值得一寫。

A題:

題目大意:能否把把N(<=50)個數分成四組,它們的和相等?

算法:搜索

優化:先對數降序排序,第一個人爲放到第一組,這樣就可以過了

 

B題:

題目大意:亂序給定一個數的各給位數,問是否存在一個組合,使得到的數能被99整除?

數學知識:

1.被9乘除的充要條件是各位之和能被9整除;

2.被11整除的充要條件是奇數位與偶數位和之差能被11整除;

其中1容易實現,對於2則要進行類似與Tug Of War那題,把它分成兩組,且使用個數和相差不超過1;(題目數據有問題,做成了和要相等,不過關係不大)

算法1:搜索

基本思路是枚舉分成兩堆,看哪一堆有哪些數字,確定了思路:

dfs(dep,sum_now,lastnum),其中dep表示當前枚舉第幾個數字,sum_now表示當前獲得的和是多少,lastnum表示上一次枚舉的是哪一個數(按升序枚舉)。

優化:

1.由於分的個數是確定的,所以可以估計出當前所能達到的最大和最小和(預先處理出在給定的數據中K個數能達到的最大和與最小和),這樣是一個很大的剪枝

2.枚舉的時候從9,8----0的順序枚舉

效率分析:

雖然理論上這個枚舉的複雜度是很高的,但由於解的分佈是很多的,所以有很大概率短時間內找到解;

另一種搜索:

 由於只有0-9這10個數字,所以可以預先記錄出這幾個數的個數,然後去枚舉有多少個,這樣的話DFS的深度就比較小;

 

算法2:DP

具體在枚舉的時候先枚舉哪一個物品,再倒序枚舉個數(正序枚舉則該物品能用無限次),最後倒序枚舉和

 

C題

題目大意:在一個N*N(N<=500),有傳送門可以傳送到任意一個門(<=1000),需要一定的時間,求在給定圖中的起點和終點的最短路?

算法:BFS

1.容易知道,傳送門不會使用多於2次;

算法1:從起始點和終點分別不考慮做BFS做出最短路,然後枚舉哪倆個門之間傳送;(STANDARD)

算法2:一開始想到SPFA,但如果純粹用SPFA,則由於傳送門的存在,可能一個點會進入隊列多次,效率比較低;於是想避免這個時間差,就得從等待時間開刀,而用BFS。

      如果拓展到傳送門,可以知道它到達其它傳送門的時間;可以不馬上進行拓展,而是等待時機成熟。

      那這個時機是什麼呢?

      以時間順序枚舉,必要的時候才用傳送門!

      當遇到傳送門時,記錄下當前可以用的傳送門可以達到的最少時間T;如果當前時間是t=T-1,則經由時間t的點集這些點到達其它點的最優解也就是T,這是時機成熟了。可以使用了!去更新以前還沒到達的傳送門,必定是達到那些傳送門的最優解。

(還有一點要注意,在必須經過傳送門的情況下的處理)

      這樣所有的傳送門的最優解都已經出來了!以後不可能再用傳送門了,已沒有意義,不可能得到比現在更優的解!

      這樣再繼續BFS,就可以得到最優解了!

 

 

D題

算法:二分

第一次二分在車上的最短時間,對於判斷則不需要用二分了(效率反而低)!因爲是順序執行的,這樣for一遍就可以解決了的!

 

E題

算法:後綴表達式

計算一個0-9,+,-,*的表達式的值,需要特別注意特殊的數據!

 

 

F題

題目大意:給定一個4X4的MATRIX,有黑白兩種狀態,變換一次可以使得5個點反色(上下左右中),求最少需要幾次操作可以使得全部同色?

算法:BFS或枚舉

1.對於BFS,很容易想,但狀態難表示,可以用狀態壓縮的方法去做,但時間效率比較低;

2.這道題有很強的規律性!

每一格只能被有限個元素改變狀態,所以可以枚舉最終的顏色,枚舉開始4個是否變色,然後從第二行開始判斷上面的這個是否需要變色,如果需要則它必須變色!這樣如果最後一行也滿足條件,則可以去更新是有次數;

效率的差距是750MS   vs   0MS

 

G題:

題目大意:矩形覆蓋的一維版本,但有10000個,且多組數據,所以N^2的算法不可以!要用NlogN的算法了!

算法是線段樹,系統學習線段樹後可以做此題!

下午寫了二叉樹版本的,對於隨機數據效果較好,但是有幾個點沒有過。

 

H題 PRO

算法:最大堆、最小堆

算法意圖很明顯,就是考這個算法,但是也有點TRICK在裏面。

在刪除數據的時候,不是隻要刪ROOT就行了,一個堆中刪除的在另外一個堆中也需要刪除!所以要用4個數組分別記錄下讀入的第I個數據在堆中的位置和堆中的元素是原來的位置!複雜度提高了!

反例:

11 2

13 12

正確的應爲7,可是不刪除數據則是8

 花了一下午的時間終於把這道題目解決了,主要是一個調試的小錯誤。

關於這道題目專門放在一篇文章中詳細講解!

 

I題

算法:線段樹RMQ

題目大意:求出數據中每K個元素的最大值

好久沒寫了,嘗試了一下,框架可以寫出來,但具體細節還是會有錯誤!

 

這次的比賽的題目很豐富!

 

USACO上的旅程有點卡了,EULER迴路就有點想不通了。爭取一下!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章