對於深度優先遍歷,可以用遞迴來實現。
遞迴有兩個關鍵點:
1.遞迴分支
2.遞迴邊界
回顧斐波那契數列:f(0)=1,f(1)=1, f(n)=f(n-1)+f(n-2) (n>=2),每當求f(n)時,將其分為f(n-1)和f(n-2),對f(n-1)與f(n-2)又可以再分,直到分到最底層的f(0)和f(1),這時候便開始向上回溯,其時間複雜度為o(2^n),
eg:pintia 上的乙個例子:
有n件物品,每件重量為w[i],價值為c[i],現選出若干物品,放入容量為v的揹包裡,使得總質量不超過v的情況下價值最大,求最大價值。(1<=n<=20)
#includeusing namespace std;
const int maxn=30;
int n,v,maxvalue = 0; //n件物品,揹包容量為v,最大價值為maxvalue
int w[maxn],c[maxn]; //w[i]是每件物品的重量,c[i]是其價值
void dfs(int index ,int sumw,int sumc)
dfs(index+1,sumw,sumc); //不選中index件物品
dfs(index+1,sumw+w[index],sumc+c[index]); //選中第index件物品
} int main()
dfs(index+1,sumw,sumc);
if(sumw+w[index]<=v)
dfs(index+1,sumw+w[index],sumc+c[index]);
} }
int n,k,x,maxsumsqu=-1,a[maxn]; //在a中n個數選擇k個使得和為x,最大平方和為maxsumsqu
vectortemp,ans;
void dfs(int index ,int nowk, int sum,int sumsqu)
return;
} if(index ==n||nowk>k||sum>x)
return; //超出遞迴邊界
temp.push_back(a[index]); //把第index個數放入陣列;
dfs(index+1,nowk+1,sum+a[index],sumsqu+a[index]*a[index]);
temp.pop_back(); // 把第index個數彈出陣列
dfs(index+1,nowk,sum,sumsqu);
}
對於dfs,遞迴是最好的選擇,只有確定了遞迴邊界,遞迴的分支以及進入分支前的判斷和操作,才能寫出合適的遞迴函式; 暑期DFS相關練習
dfs就是從起點出發,走過的要做標記 從沒有標記的點中隨意挑一 個往前走,走不了就回退,此種路徑搜尋策略就稱為 深度 優先搜尋 簡稱 深搜 就是典型的不撞南牆不回頭。其實dfs就是邏輯的建立的過程 比如說選擇乙個物品後我們進行下乙個物品的選擇,但是我們也可以不選擇的這個物品然後繼續下乙個物品的選擇,...
dfs相關練習題
給定整數序列a1,a2,an,判斷是否可以從中選出若干個數,使它們的和恰好為k 輸入 n 4 a k 13 輸出 yes 13 2 4 7 public class 部分和 int k sc.nextint kk k dfs a,k,0,newarraylist public static void...
練習記錄 dfs序)
牛客每日一題 根據根右左的遍歷順序的到dfs序,再求lis即為可以選到的最多點。利用dfs序維護每種顏色的樹,大佬部落格 需要注意的是當只能取同一邊的兩個點時,要取dfs序差值最大的兩個點,可以想出反例,但不會證明。includeusing namespace std const int maxn ...