当前位置: 首页 > wzjs >正文

分局网站建设用 asp net 做 的网站

分局网站建设,用 asp net 做 的网站,汝阳网站开发,杭州萧山做网站公司ch07 - 深度优先搜索 滑雪 知识点:路径问题、最优化问题、记忆化搜索 思路: 本题是路径问题,简单的想法是 dfs 搜索所有合法路径,最长的就是答案。但一个网格中的路径数量是指数级的,这样做会超时。走到一个位置 (x,…

ch07 - 深度优先搜索

滑雪

  • 知识点:路径问题、最优化问题、记忆化搜索

  • 思路:

    • 本题是路径问题,简单的想法是 dfs 搜索所有合法路径,最长的就是答案。但一个网格中的路径数量是指数级的,这样做会超时。
    • 走到一个位置 (x, y) 时,实际上只关心 (x, y) 往后还能走多长,而不是对于所有到达 (x, y) 的路径,都要继续往后搜索所有走法。
    • dfs(x, y):从 (x, y) 出发,往后最多还能走多长。
      • 下一步有 4 种选择,枚举 (x, y) 下一步能到达的位置 (cx, cy),所有选择对应的结果取最大值就是 dfs(x, y) 的结果。
      • 要计算 ( x , y ) → ( c x , c y ) → ⋯ (x, y)\to (cx, cy)\to \cdots (x,y)(cx,cy) 的最大长度,首先有 ( x , y ) (x, y) (x,y) 这一个位置,再调用 dfs(cx, cy) 得到 ( c x , c y ) → ⋯ (cx,cy)\to \cdots (cx,cy) 的最大长度,所以这种选择对应的结果是 1 + dfs(cx, cy) 。
    • 用记忆化搜索,f[x][y] 记录 dfs(x, y) 的结果,只要 f[x][y] 已经算过了,再次搜索到 dfs(x, y) 时可以直接返回结果。
    • 每一个状态 (x, y) 只需要被计算一次,时间复杂度 O ( R C ) O(RC) O(RC)
  • 代码:

    int dfs(int x, int y) {if (f[x][y]) return f[x][y];f[x][y] = 1; // 从(x,y)出发,最少也有它本身一个位置的长度for (int i = 0; i < 4; i++) {int cx = x + dx[i], cy = y + dy[i];if ((x, y)走到(cx,cy)不合法) continue;f[x][y] = max(f[x][y], dfs(cx, cy) + 1); // 从不同走法中取最长的}return f[x][y];
    }
    
  • 易错点:注意最长的路径不一定是从左上角出发的,根据 dfs(x, y) 的功能,思考 main() 函数怎么写才能得到正确答案。

水桶装水

  • 知识点:DFS 解决判断问题、状态标记优化

  • 思路:

    • dfs(a, b):当前第一个桶的水量是 a,第二个桶的水量是 b,能否达成目标。
    • 只要 (a, b) 的后继状态中有一个能达成目标,那么 (a, b) 也能达成目标。根据题目的操作,列举所有后继状态:
      • 例如装满第一个桶,那么后继状态是 (x, b)。
      • 例如要把第一个桶的水倒入第二个桶,先计算要倒过去的水量 d,取决于第一个桶“能倒出多少水”,以及第二个桶“能接收多少水”,d = min(a, y - b),后继状态是 (a - d, b + d) 。
      • 分别对两个水桶执行三种操作,总共有六种后继状态。
    • 水倒来倒去,有可能多次搜索到同一个状态,需要用数组标记搜索过的状态。
  • 代码:

    bool dfs(int a, int b) {if (a + b == z) return true;if (vis[a][b]) return false;vis[a][b] = true;// 第一个桶往第二个桶倒水,转移水量d1。第二个桶往第一个桶倒水,转移水量d2。int d1 = min(a, y - b), d2 = min(b, x - a);// 思考如何列举六种后继状态并返回结果
    }
    

Mother’s Milk

  • 知识点:DFS 解决判断问题、状态标记优化

  • 思路:

    • 需要搜索的状态比较明显是三个桶当前各自的牛奶量。
    • 在搜索过程中,用数组将能达到的状态标记为 true,最后枚举 a 桶为空的所有状态,对于能达到的状态,从小到大输出 c 桶所剩量即可。
    • dfs 过程中,从哪个桶倒到哪个桶有多种可能,手动列举比较麻烦,也容易写错,可以两层循环枚举。
  • 代码:

    bool f[N][N][N];
    int c[3], a[3]; // c[i]表示第i个桶的容量,a[i]表示当前状态第i个桶的牛奶量
    // 从第i个桶倒到第j个桶
    void pour(int i, int j) {int d = min(a[i], c[j] - a[j]);a[i] -= d;a[j] += d;
    }
    // 当前搜索状态是(a[0], a[1], a[2])
    void dfs() {if (f[a[0]][a[1]][a[2]]) return ; // 记忆化f[a[0]][a[1]][a[2]] = true;int b[3];memcpy(b, a, sizeof(a)); // b用来临时储存a数组的值for (int i = 0; i < 3; i++) {for (int j = 0; j < 3; j++) {if (i == j) continue;pour(i, j);dfs();memcpy(a, b, sizeof(b)); // pour()中a数组的值被修改,此处要改回来}}
    }
    int main() {cin >> c[0] >> c[1] >> c[2];a[2] = c[2];dfs();for (int i = 0; i <= c[2]; i++) { // c桶所剩量for (int j = 0; j <= c[2] - i; j++) { // b桶所剩量if (f[0][j][i]) {cout << i << " ";break;}}}return 0;
    }
    

Cows on Skates

  • 知识点:网格路径问题、DFS 搜索优化

  • 思路:

    • 本题属于需要记录路径的网格路径问题,但网格规模较大,路径数量太多,罗列所有路径会超时。
    • 优化1:题目中路径可以走重复位置,但仍然可以限制同一条路径不允许走重复位置,因为对于“走到终点”这个目标来说,绕圈是没有意义的。
    • 优化2:如果搜索过一个位置 (x, y) ,这个位置无法到终点,那么其他路径也无需再尝试这个位置了。
      • 因为 (x, y) 无法到终点分为 2 种情况:一是被障碍挡住,那么显然这个位置没有前途,其他路径也无需走这里;二是被路径中的其他位置 (x1, y1) 挡住,那么 (x1, y1) 比 (x, y) 更接近终点,应该回退到 (x1, y1) 去搜索,其他路径也无需搜索这个比 (x1, y1) 更劣的位置。
      • 所以不是用 inPath[x][y] 标记 (x, y) 有没有在当前路径中,可以用 vis[x][y] 标记有没有搜索过 (x, y) 这个位置,这样可以保证每个位置只被搜索一次。
  • 代码:

    char ch[N][N]; // 输入的迷宫
    int n, m; // 迷宫的行数和列数
    struct P{int x, y;
    } path[N*N]; // 记录状态(路径)的数组
    bool vis[N][N]; // vis[x][y]标记(x,y)这个位置有没有搜索过
    // (x,y)是当前状态(路径)的末尾位置,len是当前路径的长度
    void dfs(int x, int y, int len) {if (vis[x][y]) return ;vis[x][y] = true;if (x == n && y == m) {// 输出结果return ;}for (int i = 0; i < 4; i++) {int cx = x + dx[i], cy = y + dy[i];if (cx < 1 || cx > n || cy < 1 || cy > m || ch[cx][cy] != '.') continue;path[len+1] = {cx, cy}; // 新位置放入路径中dfs(cx, cy, len + 1);}
    }
    int main() {// 省略输入path[1] = {1, 1}; // 注意起点放入路径中dfs(1, 1, 1);return 0;
    }
    

Cow Travelling

  • 知识点:路径问题、记忆化搜索、基本计数原理

  • 思路:

    • 与”滑雪“类似,不能去罗列所有路径,会超时。要有将原问题分解为子问题解决的思维,重复的子问题通过记忆化搜索避免重复计算,以此提高效率。
    • 关键信息是位置和时间,那么状态中应该包含位置和时间。
    • dfs(x, y, t):从 (x, y) 位置出发,经过 t 秒到达终点的路径方案数。
    • 考虑下一步到达的位置 (cx, cy),有上下左右四种走法,分为四类情况统计从 (x, y) 出发的路径方案数:
      • 从 (x, y) 走到 (cx, cy) 用掉了 1 秒,那么只剩下 t - 1 秒从 (cx, cy) 走到终点,调用 dfs(cx, cy, t - 1) 得到这一类走法的方案数。
      • 分类统计,应用加法原理。
    • 花同样的时间,走不同路径,是有可能到达同一个位置的,所以会重复搜索到同一个状态,需要记忆化搜索。
    • 答案的范围:因为题目输入的时间 T 最大是 15,每一步最多有 4 种走法选择,最多走 15 步,根据乘法原理,路径方案数不会超过 4 15 4^{15} 415 ,在 int 范围内。
  • 代码:

    int dfs(int x, int y, int t) {if (t == 0) { // 时间用完了,到达终点说明是一条满足要求的路径,方案数为1,没到终点则是0return (x == r2 && y == c2 ? 1 : 0);}if (f[x][y][t] != -1) return f[x][y][t]; // 方案数不会是-1,用-1作为f的初始值表示没搜索到这个状态f[x][y][t] = 0;for (int i = 0; i < 4; i++) {int cx = x + dx[i], cy = y + dy[i];if (cx < 1 || cx > n || cy < 1 || cy > m || ch[cx][cy] == '*') continue;f[x][y][t] += dfs(cx, cy, t - 1); // 分为往上下左右四类走法,分类用加法原理}return f[x][y][t];
    }
    
  • 拓展:

    • 为什么 dfs(x, y, t) 要定义为从 (x, y) 位置出发,经过 t 秒到达终点的路径方案数?
    • 能不能定义为从起点出发,经过 t 秒到达 (x, y) 位置的方案数?思考并尝试。
http://www.dtcms.com/wzjs/580661.html

相关文章:

  • .net网站开发程序员360指数官网
  • 婚恋网站做期货现货贵金属的人双辽做网站
  • 临淄网站推广网页设计难还是网站建设南
  • 网站外链建设大揭秘太原网络推广价格
  • 做网站去什么公司深圳做模板网站的公司
  • 辅导班广告去哪个网站做wordpress添加订阅教程
  • 做百度网站接到多少客户电话网页设计模板html代码表格
  • 摄影网站建设论文如何自己制作链接内容
  • 青岛的网站设计公司广西省建设厅网站
  • dw2019怎么做网站网站编程培训
  • 单页导航网站企业vi设计标准
  • 做代理网站杭州最好的设计公司
  • 龙华做棋牌网站建设多少钱做网站文章要一篇一篇的写吗
  • 张店做网站公司都有什么网站
  • 密云做网站的广州安全教育平台app下载
  • 驻马店网站建设熊掌号企业管理系统排名
  • 柳州网站建设工作室郑州网站推广 汉狮网络
  • 教育培训机构网站模板个人网站域名用什么好
  • 汽车便宜网站建设手机网站开发目的
  • 手机自己做网站江西省城乡建设厅网站
  • 114物流网站怎么做建行赤峰市分行 - 欢迎访问中国建设银行网站
  • 做视频网站技术壁垒在哪里医疗网站建设平台
  • 做网站好一点的公司网站建设中间件收费
  • 怎么制做网站大发快三网站自做
  • 上海公司注册网站网站设计的公司怎么样
  • vivo手机为什么建设网站成都网站设计公司排名
  • 心连网网站网站开发的公司电话
  • 哪家网站建设公司专业重庆旅游网页制作
  • 做pc端网站要多少钱买邮箱的网站
  • 企业网站建设 全包中国手机网站建设公司