记忆化DFS
例1:斐波那契数列
递推:
效率高,可以避免很多重复的计算
递归:
优点:程序很简洁
缺点:空间容易爆栈,时间慢
int dfs(int n)
{
if(n == 1 || n == 2) return 1;
else return ( dfs(n-1)+dfs(n-2) )%1000000007;
}
记忆化dfs
int dfs(int n)
{
if(fib[n]) return fib[n];
if(n == 1 || n == 2) fib[n] = 1;
else fib[n] = (dfs(n-1)+dfs(n-2))%100000007;
return fib[n];
}
先到状态数组里查找是否存在值,如果没有再处理,处理先保存值然后再返回输出,确保每个值最多算一次,每算出来就保存在数组里面
例2:01背包
递归dfs
int dfs(int i, int v)
{
if(dp[i][v]) return dp[i][v];
if(i == 0 || v <= 0) return 0;
if(w[i] > v) return dfs(i-1,v);
else return max( dfs(i-1,v), dfs(i-1,v-w[i]) + p[i] );
}
记忆化dfs求解01背包
int dfs(int i, int v)
{
if(dp[i][v]) return dp[i][v];
if(i == 0 || v <= 0) return 0;
if(w[i] > v) dp[i][v] = dfs(i-1,v);
else dp[i][v] = max( dfs(i-1,v), dfs(i-1,v-w[i]) + p[i] );
return dp[i][v];
}
上面两个问题都很容易用普通DP的方式实现,为什么还需要记忆化dfs呢?他的优势在哪里?
并不是所有的题目都方便用dp来做,有的方便用dfs做,但dfs效率不高
基于优先队列的BFS
预备知识—优先队列(priority_queue)
特点:
每次取出的是最高优先权的元素(不一定先进先出
)
创建优先队列 queue<数据类型> 队列名;
访问最优元素 队列名.top();//默认从大到小
#include <bits/stdc++.h>
using namespace std;
int main()
{
priority_queue<int> q;
int t,a = 2, b = 5, c = 3;
q.push(a); q.push(b); q.push(c);
while(!q.empty())
{
t = q.top();
q.pop();
cout << t << endl;
}
return 0;
}
struct T
{
int x, y ,z;
friend bool operator < (T t1, T t2)
{
if(t1.z != t2.z) return t1.z > t2.z;
if(t1.y != t2.y) return t1.y < t2.y;
return t1.x > t2.x;
}
}t;
int main()
{
priority_queue<T> q;
T a = {4,4,3}, b = {2,2,5}, c = {1,2,5}, d = {2,1,5};
q.push(a); q.push(b); q.push(c); q.push(d);
while(!q.empty())
{
t = q.top();
q.pop();
cout << t.x << " " << t.y << " " << t.z << endl;
}
return 0;
}
输出结果:
4 4 3
1 2 5
2 2 5
2 1 5