首页 > 其他分享 >击杀黄金蛋糕人马(dfs + 记忆化搜索)(难)

击杀黄金蛋糕人马(dfs + 记忆化搜索)(难)

时间:2023-07-15 12:23:10浏览次数:22  
标签:ch int dfs ways 击杀 蛋糕 include

 

题解:

  

这段代码实现了一个递归的记忆化搜索算法,用于解决一个求最大蛋糕面积下限的问题。下面解释一下其递归思路:

  1. 定义状态

设 ways[w][h][m] 表示当前蛋糕的宽度为 w,高度为 h,已经切了 m 刀时,最大蛋糕面积的下限。

  1. 状态转移

对于当前的蛋糕,可以选择竖着切一刀或者横着切一刀。竖着切一刀会将蛋糕分成两块,横着切一刀也会将蛋糕分成两块。因此,可以枚举第一刀的位置,再递归求解剩下的部分,得到最大蛋糕面积的下限。具体地,可以使用两个变量 i 和 k,其中 i 表示第一刀的位置,k 表示前 k 刀已经切好了,剩下的 m-1-k 刀还未切。则切下来的蛋糕面积为 w * i 或 h * i ,剩下的蛋糕面积为 (w - i) * h 或 w * (h - i) 。因此,递归求解得到的两个面积的较大值即为当前状态的最大蛋糕面积下限。

  1. 基础情况

当 w * h < m+1 时,无法分出 m+1 块蛋糕,返回正无穷表示无法分割。当 m=0 时,说明已经切好了,返回当前蛋糕的面积。

  1. 记忆化搜索

为了避免重复计算,可以使用记忆化搜索来保存已经求解过的状态,遇到重复状态时直接返回已经计算好的结果。

  1. 递归返回值

最终递归返回的值为 ways[w][h][m],即当前状态的最大蛋糕面积下限。

综上所述,该递归算法通过不断地切割蛋糕,并记录当前状态的最大蛋糕面积下限来求解问题,实现了记忆化搜索,同时也避免了重复计算,提高了程序的效率。

 

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <cmath>
 5 #include <cstring>
 6 #include <vector>
 7 #include <map>
 8 #include <stack>
 9 #include <queue>
10 #include <deque>
11 #include <list>
12 #include <set>
13 #include <cctype>
14 
15 using namespace std;
16 
17 inline int read(int &s)
18 {
19     s = 0;
20     int w = 1;
21     char ch = getchar();
22     while (ch < '0' || ch > '9')
23     {
24         if (ch == '-')
25             w = -1;
26         ch = getchar();
27     }
28     while (ch >= '0' && ch <= '9')
29     {
30         s = s * 10 + ch - '0';
31         ch = getchar();
32     }
33     return s * w;
34 }
35 
36 inline void write(int x)
37 {
38     if (x < 0)
39     {
40         putchar('-');
41         x = -x;
42     }
43     if (x > 9)
44         write(x / 10);
45     putchar(x % 10 + '0');
46 }
47 
48 const int N = 30, INF = 0x3f3f3f3f;
49 int ways[N][N][N * N]; // 切法的记忆化搜索
50 // ways[w][h][m]表示当前蛋糕宽度为w,高度为h,已经切了m刀时,最大蛋糕的面积下限
51 
52 // 最大蛋糕的面积下限
53 int dfs(int w, int h, int m) // m为切的刀数
54 {
55     if (w * h < m + 1) // 分不出那么多块
56         return INF;
57     if (m == 0)
58         return w * h;        // 切好了
59     if (ways[w][h][m] != -1) // 记忆
60         return ways[w][h][m];
61 
62     int mincake = INF;
63     for (int i = 1; i < w; ++i)     // 第一刀是竖着切的,第一刀可以有 w - 1 个位置,i表示第一刀的位置
64         for (int k = 0; k < m; ++k) // k表示前k刀已经切好了,剩下的 m - 1 - k 刀还未切
65         {
66             int m1 = dfs(i, h, k);               // 切下来的蛋糕
67             int m2 = dfs(w - i, h, m - 1 - k);   // 剩下的蛋糕
68             mincake = min(mincake, max(m1, m2)); // m1, m2中较大值才是最大蛋糕的最小值
69         }
70 
71     for (int i = 1; i < h; ++i) // 第一刀是横着切的
72         for (int k = 0; k < m; ++k)
73         {
74             int m1 = dfs(w, i, k);
75             int m2 = dfs(w, h - i, m - 1 - k);
76             mincake = min(mincake, max(m1, m2));
77         }
78 
79     ways[w][h][m] = mincake;
80 
81     return ways[w][h][m];
82 }
83 
84 int main()
85 {
86     int w, h, m;
87     while (cin >> w >> h >> m && w != 0 && h != 0 && m != 0)
88     {
89         memset(ways, -1, sizeof(ways));
90         cout << dfs(w, h, m - 1) << endl;
91     }
92     // system("pause");
93     return 0;
94 }

 

标签:ch,int,dfs,ways,击杀,蛋糕,include
From: https://www.cnblogs.com/nijigasaki14/p/17555926.html

相关文章

  • Codeforces Round 881 (Div. 3) D - Apple Tree(dfs)
    https://codeforces.com/contest/1843/problem/D题目大意:一颗树中,每次给定两个结点,每个结点都可以移动到孩子结点,最后可以到达叶子结点,问我们这两个结点最终移到叶子结点有多少种组合?(其实就是让求以这两个节点为根的子树的叶子结点个数的乘积)input2512345332......
  • Python使用hdfs上传文件至hadoop报错
    报错代码:fromhdfs.clientimportClienthdfs_client=Client('http://IP:端口')hdfs_client.makedirs(hdfs_dir)在与hadoop创建链接后建文件夹时报错报错信息:requests.exceptions.ConnectionError:('Connectionaborted.',BadStatusLine('\x00\x00\x00|{\......
  • luogu1_dfsbfs
    普及练习场知识点汇总:DFS、BFS、☆杨辉三角P1118USACO06FEB数字三角形☆求解的个数用深搜,求最优解用广搜。DFSP1219八皇后弱智一样的我,还建立NxN的矩阵来模拟。结果呢,检查(check)时要遍历整个棋盘,最终导致只能过部分。根本不用二维矩阵。dfs(i),因为传进来的i是行号,......
  • nginx: [emerg] unknown directive "ngx_fastdfs_module" in /usr/local/src/nginx-1.
    一、问题说明:搭建fastDFS集群时,提示错误信息为:nginx:[emerg]unknowndirective"ngx_fastdfs_module"in/usr/local/src/nginx-1.10.0/conf/nginx.conf:52        通过分析加载fastdfs模块出错二、配置完信息后在,执行nginx-V  发现没有fastdfs的相关内......
  • 解决root用户对HDFS文件系统没有权限的问题
    解决root用户对HDFS文件系统没有权限的问题说明:HDFS文件系统的目录基本都属于supergroup超级用户组,所以就把用户添加到该用户组,即可解决很多权限问题。第一步:在Linux执行如下命令增加supergroup用户组groupaddsupergroup第二步:然后将用户root增加到supergroup用户组......
  • abc070d <简单树上dfs>
    D-TransitTreePath//https://atcoder.jp/contests/abc070/tasks/abc070_d//<简单树上dfs>#include<iostream>#include<algorithm>#include<vector>usingnamespacestd;usingLL=longlong;constintN=1e5+10;structNode{......
  • abc309e <dfs>
    E-FamilyandInsurance//https://atcoder.jp/contests/abc309/tasks/abc309_e//<dfs>//关键在于意识到,每个结点保留最大后代数即可#include<iostream>#include<algorithm>#include<vector>usingnamespacestd;typedeflonglongLL;constintN=3......
  • 解决MongoDB之Gridfs的具体操作步骤
    MongoDB之GridFS什么是GridFSGridFS是MongoDB的一种存储文件的方式,它可以用于存储和检索大型文件。在传统的MongoDB中,适合存储的文件大小通常限制在16MB以内,而GridFS可以突破这个限制,支持存储非常大的文件。GridFS将大文件分割为小块,每个小块都被存储为一个MongoDB文档。同时,Gri......
  • c语言刷dfs和bfs合集(含回溯)
    目录1.dfs和bfs区别,解决不同的问题2.bfs3.dfs1.dfs和bfs区别,解决不同的问题通常来说,BFS适用于求最短路径,DFS用来解决最长匹配、连通性这些问题比较方便【例1】1091.二进制矩阵中的最短路径链接1:https://leetcode.cn/problems/shortest-path-in-binary-matrix/solution/......
  • 搭建CDH后,hdfs的权限问题设置
    搭建CDH后,hdfs的权限问题问题描述:搭建cdh集群后,在hdfs中创建文件报错:Permissiondenied:user=root,access=WRITE,inode=“/“:hdfs:supergroup:drwxr-xr-x即使使用root账户也是一样。无论是用sudohadoopdfs-mkdir建立文件还是put文件,都会显示,同样的错误!!经过百度发现......