这周主攻的搜索算法,大部分是在看题目,题目比知识来的更灵活,更具有提高性。通过看搜索,发现用选择用深搜或广搜解决问题,要根据题目具体解决。但是很多问题,两种方法都是可以用的,只不过一种更容易实现,一种更难实现的问题。
目录
背包问题
深度优先搜索队列实现
剪枝搜索算法优化
洛谷P3958奶酪
搜索与排序结合
搜索与贪心
感受
背包问题(原文章)
这个问题是我在刚接触搜索时就接触的一类问题。在背包一定的容量下,实现物品的最大价值。
这里用的是暴力搜索的方法,时间复杂比较高。
const int N = 100;
int n, w;
int W[N], V[N];
int max(int a, int b)
{
return a > b ? a : b;
}
//从第i个物品开始挑选总重小于j的部分
int solve(int i, int j)
{
int res;
if (i == n)//已经没有剩余的物品了
res = 0;
else if (j < W[i])
res = solve(i + 1, j);
else
{
res = max(solve(i + 1, j), solve(i + 1, j - W[i]) + V[i]);
//一个物品选还是不选都试一下
}
return res;
感悟:这是在背包中的一个经典的问题,题解用的是暴力搜索,一旦n过大题目就会出错,所以,以上算法还有待优化。
深度优先搜索队列实现(链接)
给出一个m*n矩阵,矩阵中的元素为零或为1。称位置(x,y)与其上下左右四个位置(x,y+1)、(x,y+1)、((x,y-1)、(x+1,y)、(x-1,y)是相邻的。
int n,m;//矩阵的大小为n*m
int matrix[maxn][maxn]; //01矩阵
bool inq[maxn][maxn]={false};//记录位置x,y是否入过队
int X[4]={0,0,1,-1};//增量数组
int Y[4]={1,-1,0,0};
bool judge(int x,int y){//判断坐标x,y是否需要访问
//越界返回false
if(x>=n||x<0||y>=m||y<0) return false;
//当前位置为0,或x,y移入过队,返回false
if(matrix[x][y]==0||inq[x][y]==true)return false;
//以上都不满足
return true;
}
//BFS函数访问位置x,y所在块,将该块所有1的inq都设置为true;
void BFS(int x,int y){
Node.x=x;
Node.y=y;//当前节点的坐标为x,y;
queueQ;
Q.push(Node);//将结点Node入队
inq[x][y]=true;
while(!Q.empty()){
node top=Q.front();//取出队首元素
Q.pop();
for(int i=0;i<4;i++){
int newx=top.x+X[i];
int newy=top.y+Y[i];
if(judge(newx,newy)){
Node.x=newx;Node.y=newy;
Q.push(Node);
inq[newx][newy]=true;//设置位置newx,newy已入过队
}
}
}
感悟:小技巧是,对于当前位置的(x,y)来说,由于与其相邻的四个位置分别为(x,y+1)、(x,y-1)、(x+1,y)、(x-1,y),那么不妨设置两个增量数组,来表示四个方向。
int X[]={0,0,1,-1} int Y[]={1,-1,0,0}这样就可以用for循环来枚举4个方向。
剪枝搜索算法优化(题目链接)
剪枝可以尽可能的优化算法的执行效率,题目大概是抢劫钻石的重量一定,获取最大的价值。当时一看到题目就着手用数组去做,但是由于数组数量的限制,一直通过不了,看似是背包问题,其实不是。由于其中一个数据在小范围内。于是选择通过dfs+剪枝的操作。
洛谷P3958奶酪(题目链接)
这道题用搜索可以拿满分,其他的方法多少会有点缺陷,用深度优先搜索速度上很快。首先,我们找出所有可以从下表面进入的球,然后深度优先搜一遍。一旦遇到一个点最高处高度\;z+r \ge h\;z+r≥h,就表示可以到上表面,退出。因为每个洞最多访问一次(只需要求是否能到达上表面,而不是最短步数),然后决定下一步的时候还需要O(n)O(n)的时间。所以总复杂度O(n^2)O(n2)。
搜索与排序结合
一般情况下,直接用搜索会更复杂,如果用排列好的数,再用广搜或深搜那么,搜索用起来会更容易。
搜索与贪心(原文链接)
贪心是寻求问题的最优解,如果先用贪心获得通往优解的那条路,再用搜索,那么便如鱼得水。
感受:
通过题目去复习和加强知识的方法是非常高效的。我自己在网课期学习的效果真不如线下,自律和坚持很重要,希望自己再努把力。知识是死的,要运用起来才有意义。所以,我要加强平时的练习,向标准靠拢。