DFS剪枝策略总结

  1. 优化搜索顺序 优先搜索分支数少(剩余选择少)的情况
  2. 排除等效冗余 若对顺序没有要求 可以将排列转化为组合
  3. 可行性剪枝 不合法的情况不进行搜索
  4. 最优化剪枝 若当前的"消耗"已经超过暂存的答案 直接返回
  5. 记忆化搜索(DP)

AcWing 165.小猫爬山

翰翰和达达饲养了 N 只小猫 这天 小猫们要去爬山

经历了千辛万苦 小猫们终于爬上了山顶 但是疲倦的它们再也不想徒步走下山了

翰翰和达达只好花钱让它们坐索道下山

索道上的缆车最大承重量为 W 而 N 只小猫的重量分别是 C1、C2……CN

每辆缆车上的小猫的重量之和不能超过W

每租用一辆缆车 翰翰和达达就要付 美元 所以他们想知道

最少需要付多少美元才能把这N只小猫都运送下山?

输入格式

第 1 行:包含两个用空格隔开的整数 N 和 W

第 2~N+1 行:每行一个整数 其中第 i+1 行的整数表示第 i 只小猫的重量 Ci

输出格式

输出一个整数,表示最少需要多少美元,也就是最少需要多少辆缆车。

数据范围

1≤N≤18
1≤Ci≤W≤10^8

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 20;
int w[N], sum[N];//小猫重量和每辆车上当前的载重
int n, limit, ans;//考虑到第u只猫 已经用了k辆车
void dfs(int u, int k)
{//DFS剪枝优化(最优性剪纸)//当前情况已经比在暂存答案更差了 就不用继续搜了if (k >= ans)return;//搜到了一个更优的方案 更新答案if (u == n)ans = k;//当前有k辆车 有k种放置选择for (int i = 0; i < k; i++){//DFS可行性剪枝//必须满足条件才能放入if (sum[i] + w[u] <= limit){//放入猫猫sum[i] += w[u];dfs(u + 1, k);//恢复现场sum[i] -= w[u];}}//新开一辆车也是一种选择//k从0开始 sum[k]其实是指第k+1辆车sum[k] = w[u];dfs(u + 1, k + 1);sum[k]=0;//恢复现场
}int main()
{cin >> n >> limit;ans = n;for (int i = 0; i < n; i++)cin >> w[i];//DFS优化搜索顺序//先搜索分支少的//先放入重猫 这样剩下来的选择更少sort(w, w + n);reverse(w, w + n);dfs(0, 0);cout << ans << endl;return 0;
}

AcWing 166. 数独

你需要把一个 9×9 的数独补充完整

使得图中每行、每列、每个 3×3 的九宫格内

数字 1∼9 均恰好出现一次。

请编写一个程序填写数独。

输入格式

输入包含多组测试用例。

每个测试用例占一行,包含 81 个字符,代表数独的 81 个格内数据

(顺序总体由上到下 同行由左到右)

每个字符都是一个数字(1−9)或一个  .(表示尚未填充)。

您可以假设输入中的每个谜题都只有一个解决方案。

文件结尾处为包含单词 end 的单行,表示输入结束。

输出格式

每个测试用例,输出一行数据,代表填充完全后的数独。

输入样例:

4.....8.5.3..........7......2.....6.....8.4......1.......6.3.7.5..2.....1.4......
......52..8.4......3...9...5.1...6..2..7........3.....6...1..........7.4.......3.
end

输出样例:

417369825632158947958724316825437169791586432346912758289643571573291684164875293
416837529982465371735129468571298643293746185864351297647913852359682714128574936
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 9;
const int M = 1 << N;
//状态压缩 行 列 九宫格 用二进制数表示状态
int row[N], col[N], cell[3][3];
char str[N*N+10];//存图
//求二进制数中有多少个1
//求以2为底的对数
int ones[M], map[M];//最开始什么数都没填入
//所有二进制位都为1 表示可以填
void init()
{//二进制位全部设置位1//二进制的第0位到第8位表示1-9for (int i = 0; i < N; i++)row[i] = col[i] = (1 << N) - 1;for (int i = 0; i < 3; i++)for (int j = 0; j < 3; j++)cell[i][j] = (1 << N) - 1;
}//在(x,y)填上t
//把(x,y)这个位置的数删掉
void draw(int x, int y, int t, bool is_set)
{//is_set==true 表示填入//二维坐标压缩到一维(注意要从0)开始//t是0-8//因为初始化的时候 二进制第0位设为1if (is_set)str[x * N + y] = '1' + t;else str[x * N + y] = '.';//获取填入t时对应修改的二进制位int v = 1 << t;if (!is_set)v = -v;//删除时要减去row[x] -= v;col[y] -= v;cell[x / 3][y / 3] -= v;
}int lowbit(int x)
{return x & (-x);
}//分析(x,y)填入哪些数是合法的
int get(int x, int y)
{return row[x] & col[y] & cell[x / 3][y / 3];
}bool dfs(int cnt)
{//没有剩余的空格了 意味着填完了if (!cnt)return true;//寻找可以填的数(的情况)最少的的空格//DFS的搜索顺序优化//希望刚开始搜索时的分支数目尽可能少int minv = 10;int x, y;for(int i=0;i<N;i++)for(int j=0;j<N;j++)if (str[i * N + j] == '.')//二维映射到一维{int state = get(i, j);if (ones[state] < minv){minv = ones[state];x = i, y = j;}}int state = get(x, y);for (int i = state; i; i -= lowbit(i)){//lowbit(i)获取最低位的1//i-=lowbit(i)相当于将最低位的1改为0//lowbit(i)返回的是2的某次方 次方数对应填写的数字int t = map[lowbit(i)];draw(x, y, t, true);if (dfs(cnt - 1))return true;draw(x, y, t, false);//恢复现场}//DFS函数最后通常会有一个return false//当该层的搜索循环迭代完都没有return true的机会//说明该层的所有情况都不行了//应当返回到上一层 撤销这次错误的尝试(恢复现场)//return true 一般在开头return false;
}int main()
{//求以2为底的对数for (int i = 0; i < N; i++)map[1 << i] = i;//求二进制数中有多少个1for (int i = 0; i < 1 << N; i++)for (int j = 0; j < N; j++)ones[i] += (i >> j) & 1;while (cin >> str, str[0] != 'e'){init();//cnt表示有多少个空位int cnt = 0;//把一行字符串映射到9X9的二维数组for (int i = 0, k = 0; i < N; i++)for (int j = 0; j < N; j++, k++)if (str[k] != '.'){//t是0-8//因为初始化的时候 二进制第0位设为1int t = str[k] - '1';//将字符覆盖为数字draw(i, j, t, true);}else cnt++;dfs(cnt);puts(str);}return 0;
}

DFS剪枝优化 小猫爬山 数独相关推荐

  1. 【AcWing 165】 小猫爬山 简单dfs + 剪枝优化

    翰翰和达达饲养了N只小猫,这天,小猫们要去爬山. 经历了千辛万苦,小猫们终于爬上了山顶,但是疲倦的它们再也不想徒步走下山了(呜咕>_<). 翰翰和达达只好花钱让它们坐索道下山. 索道上的缆 ...

  2. 生日蛋糕 dfs剪枝优化

    7月17日是Mr.W的生日,ACM-THU为此要制作一个体积为Nπ的M层生日蛋糕,每层都是一个圆柱体. 设从下往上数第i(1 <= i <= M)层蛋糕是半径为Ri, 高度为Hi的圆柱.当 ...

  3. szucodeforce训练1081C组合数学lucas定理,div2 627的D dfs +剪枝优化,697D Puzzles{dfs序+概率}

    给你n个方格排成一行,有m种颜色,然后要把这n个方格分成k+1段,每段涂不同的颜色,问有多少种方法. 组合数学Lucas定理 排列组合问题,首先要在n-1个位置里面选出k个位置当作段与段的分割点,然后 ...

  4. DFS(剪枝与优化) - 洛谷 P1361 - 小猫爬山

    DFS(剪枝与优化) - 洛谷 P1361 - 小猫爬山 翰翰和达达饲养了N只小猫,这天,小猫们要去爬山. 经历了千辛万苦,小猫们终于爬上了山顶,但是疲倦的它们再也不想徒步走下山了(呜咕>_&l ...

  5. 小猫爬山(dfs剪枝)

    Description 翰翰和达达饲养了 N 只小猫,这天,小猫们要去爬山. 经历了千辛万苦,小猫们终于爬上了山顶,但是疲倦的它们再也不想徒步走下山了 翰翰和达达只好花钱让它们坐索道下山. 索道上的缆 ...

  6. 深度优先搜索(DFS) 总结(算法+剪枝+优化总结)

    深度优先搜索(DFS) 总结(算法+剪枝+优化总结) 本文中会引用部分实例.文献资料来自不同的作者之手,由于资料整理比较困难,转载地址不在文中列举.如有侵权请联系我更换或删除!对于提供题解思路的各位大 ...

  7. 算法第十期——DFS(深度优先搜索)的剪枝优化

    目录 DFS:剪枝 DFS:有哪些剪枝方法 DFS例题一:剪格子 [思路] DFS例题二:路径之谜 [样例分析] DFS例题三:四阶幻方 [思路] [做法一] [做法二] DFS例题三:分考场 [样例 ...

  8. DFS剪枝——poj3074数独

    题目连接 Description In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 ...

  9. acwing165.小猫爬山

    做题心得Acwing165.小猫爬山 题目 翰翰和达达饲养了N只小猫,这天,小猫们要去爬山. 经历了千辛万苦,小猫们终于爬上了山顶,但是疲倦的它们再也不想徒步走下山了(呜咕>_<). 翰翰 ...

最新文章

  1. sql loader 导入数据时的问题
  2. html去除边角,WEB开发向HTML5及CSS3迈进(1)——圆框边角的处理
  3. LeetCode 1484. 克隆含随机指针的二叉树(哈希/递归)
  4. I2C总线信号时序总结
  5. document.mozFullScreen
  6. C++安全方向openssl(一):1.2 Linux下编译openssl3.0并编写测试项目
  7. ViT (Vision Transformer) ---- SimpleRNN + Self-Attention
  8. PTA — 单词长度 (15 分)
  9. iOS开发之报错:IntxLNK
  10. Chrome 76.0.3809.100(正式版本) (64 位) 版本 77.0.3865.90不显示网址中的www怎么解决...
  11. android选择图片,通过uri获取路径
  12. VMware Workstation 16.2 Pro for Windows SLIC 2.6 Unlocker
  13. ES6/7 + Babel 编译器-郭永峰-专题视频课程
  14. 微信表情存入mysql
  15. 二分之一波长传输线有啥用?
  16. 小球斜抛公式用C语言怎么写,利用C4droid绘制小球斜抛运动轨迹(考虑空气阻力)...
  17. Surface Pro的MicroSDHC卡测速
  18. web前端设计与开发期末作品/期末大作业:我的家乡——走进达州(4页) HTML+CSS+JavaScript
  19. 海洋测绘 知识点 详细
  20. mysql fabric HA测试

热门文章

  1. 后台架构实战——Spring框架搭建
  2. 夏普将在迪拜推出植物工厂种草莓
  3. Win11 桌面快捷方式未全部显示的诡异现象及解决方法
  4. 【python脚本系列】MIDI文件128种音色码表
  5. 前端打卡day3--html-表格
  6. Arduino控制PCA9685作为GPIO使用
  7. c语言china大写变小写,英语字母大写小写
  8. SecureCRT使用说明
  9. v-if和v-else和v-else的使用
  10. #142-(EZOI高精度练习)[高精度]天使的宣誓