提升組刷題營 DAY 1 下午

DFS

深度優先搜索

經過搜索獲得一棵樹形圖函數

策略:只要能發現沒走過的點,就走到它。有多個點可走就隨便挑一個,若是無路可走就回退,再看有沒有沒走過的點可走。spa

在圖上尋找路徑【少數可用最短路解決】:最短路不能解決路徑有順序的,也就是若是路徑的邊權與以前通過的點火這路有關,那就只能深搜code

解決遞歸形式的問題blog

有後效性的選擇問題遞歸

組合問題隊列

狀態可能不少,所以數據範圍通常較小源碼

一、狀態表示 class

二、剪枝 效率

       剪枝的方法: 擴展

              最優答案剪枝

              記憶化剪枝

              可行性剪枝

              ……

 

一、洪水[ 1s 32M ] 

題解

數據範圍小,搜索

 

 

 

 

 

 

 

二、辛苦的老園丁 [1s 128M] [1s 32M] 

 

 題解

建反圖找團(簡單地說,團是G的一個徹底子圖)

原來輸入建圖是標記的兩點之間不能有連邊,建反圖以後,連邊的就是能夠連通的

剪枝:

1.若是一個點與點i當前沒有連邊,那麼以後永遠都不會連邊,那麼就能夠把點i從最大團候選中刪掉

2.利用可行點剪枝  sum+tot<=ans ,捨棄

3.利用當前答案剪枝ans(2)+tot<=ans

(tot 是團不斷累加的權值,sum是序列裏面剩下的全部東西的權值和

    若sum+tot<=ans ,捨棄)

可能組成最大團的點一開始在一個序列裏

取出一個點,不斷擴展,當序列爲空,擴展完了

首先拿出1 ,那麼序列被更新爲與1相連的點

不斷擴展,直到隊列爲空,找完團了

 

 

 

 

 

 

 

 

 

 

 --->sum+tot<=ans 

 

 

最大團主函數:

 

 爲何找最大團而不是最大獨立集呢??

 

 

三、生日蛋糕 [ 1s 10M] 

 

 題解

 

 

 

 

 

 

 

 

四、靶形數獨[2s128M] 

 

 

 

 

 題解

 

 

 

 

 

 

 

 

 

五、棋盤分割 [1s 16M] 

 

 題解

 

 

 

 

 

 

 


 

BFS 

寬度優先搜索

 

 

一、密室逃脫 [ 1s 64M ] 

 

 題解

queue<pair<int,int> > Q;
int FindPath(pair<int,int> b,pair<int,int> e) {
    for (int i=0;i<n;++i) for (int j=0;j<m;++j) dis[i][j]=1e9+10;
    Q.push(b); dis[b.first][b.second]=0;
    while (!Q.empty()) {
        pair<int,int> u=Q.front(); Q.pop();
        int x=u.first,y=u.second;
        for (int i=0;i<4;++i) {
            int tx=x+dx[i],ty=y+dy[i];
            if (CoordValid(tx,ty) && mp[tx][ty]!=0 && dis[tx][ty]>dis[x][y]+1) {
                dis[tx][ty]=dis[x][y]+1;
                Q.push(make_pair(tx,ty));    
            }
        }
    }
    return dis[e.first][e.second];
}

 

 

二、Prime Path[ 1s 64M ] 

 

 

 題解

記錄當前素數的值

每次選擇一個位置,將其該改成另外一個數

檢查新的數是不是素數

 

 

 

 

 

三、拯救行動 [ 1s 64M ] 

 

 

 題解

 

 

(Python源碼)

BFS部分

 

 

 

 

 

 

四、抓住那頭牛 [ 1s 64M ] 

 

 

 題解

 

 

 

 

 

 BFS

 

 

 

 

雙向BFS(DBFS)

 

 

 

對比BFS和DFS 

廣搜通常用於狀態表示比較簡單求最優策略的問題l

優勢:是一種完備策略,即只要問題有解,它就必定能夠找到解。而且,廣度優先搜索找到的解,還 必定是路徑最短的解。

缺點:盲目性較大,尤爲是當目標節點距初始節點較遠時,將產生許多無用的節點,所以其搜索效率較低。須要保存全部擴展出的狀態,佔用的空間大

深搜幾乎能夠用於任何問題

只須要保存 從起始狀態到當前狀態路徑上的節點

根據題目要求憑藉本身的經驗和對兩個搜索的熟練程度作出選擇

 

 


 

枚舉

一、蘋果消消樂 [ 1s 64MB] 

 

 

 題解

選擇連續的香蕉時最優

枚舉選擇的香蕉起始位置,計算答案

 

 

 

二、Matrix  [ 2s  512MB ]  

 

 題解

 

 

 Check函數:

 

 

四、特殊密碼鎖[ 1s 64M ]

 

 

 題解

一、  已知,在首位狀態固定後,後續的操做是肯定的。

二、  只須要枚舉首位是否按便可。

 

 

 

 

五、惱人的青蛙[ 2s 64M ] 

 

題解

①不是一條行走路徑:只有兩棵被踩踏的水稻;

②是一條行走路徑,但不包括(2,6)上的水道;

③不是一條行走路徑:雖然有3棵被踩踏的水稻,

但這三棵水稻之間的距離間隔不相等。

例如,圖4的答案是7,

由於第6行上所有水稻剛好構成一條青蛙行走路徑。

 

 

 

 

 

 

 題解

 

 

枚舉主函數

 

 

 

枚舉獲得最大步數

 

 

 

重識枚舉

枚舉:基於已知信息的猜想,從可能的答案集合中枚舉並驗證

驗證複雜度儘量小

枚舉範圍儘量小(利用條件縮小枚舉空間)

選擇合理的枚舉順序(正序,倒序)

枚舉什麼?

怎麼枚舉?

怎麼減小枚舉?

 

 


二進制枚舉

五、熄燈問題[ 1s 64M ] 

 

 

 

 

 題解

 

 

 

 

 二進制枚舉

推導最後一行

 

 

二進制枚舉

二進制的枚舉通常用以枚舉集合

對集合的枚舉涉及到不一樣的集合內部元素的選擇

枚舉子集

         for(int S1=S;S1!=0;S1=(S1-1)&S){

    S2=S^S1;

}

相關文章
相關標籤/搜索