UVa1629 记忆化搜索 分格子
来源:互联网 发布:傲虎网络 编辑:程序博客网 时间:2024/05/29 12:32
题意:n*m大小的蛋糕,被分成n*m个区域,其中k个区域上面有樱桃。你需要把蛋糕切成k份,每份都有樱桃,切的时候只能水平或竖直沿着网格线切,切到底。问最短切的长度是多少。
思路:DP。DP[u][d][l][r]。u,d,l,r表示整块蛋糕的上下左右。一块大蛋糕的最优切法一定也是它分成两块以后的最优切法,枚举每种切法记忆化搜索可解。状态转移方程见代码。
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<cmath> #include<algorithm> using namespace std; const int INF = 0x3f3f3f3f; int n, m, dp[25][25][25][25]; bool has[25][25]; //记录格点是否有樱桃 int sum(int u, int d, int l, int r) //统计区域的樱桃数 { int ret = 0; for (int i = u + 1; i <= d; ++i) for (int j = l + 1; j <= r; ++j) { if (has[i][j]) ++ret; if (ret == 2) return 2; //超过两个也就是多个的情况可以统一递归处理,直接视为同一情况 } return ret; } int dfs(int u, int d, int l, int r) { int &ret = dp[u][d][l][r]; if (ret != -1) return ret; int total = sum(u,d,l,r); if (total == 1) return ret = 0; //一个樱桃返回0,无需切割了 if (!total) return ret = INF; //没有樱桃,无效切割 ret = INF; for (int i = u + 1; i < d; ++i) //水平切割 ret = min(ret, dfs(u,i,l,r) + dfs(i,d,l,r) + r - l); for (int i = l + 1; i < r; ++i) //垂直切割 ret = min(ret, dfs(u,d,l,i) + dfs(u,d,i,r) + d - u); return ret; } int main() { int k, x, y, kase = 0; while(cin >> n >> m >> k) { memset(dp, -1, sizeof dp); memset(has, 0, sizeof has); for (int i = 0; i < k; ++i) cin >> x >> y, has[x][y] = 1; cout << "Case " << ++kase << ": " << dfs(0, n, 0, m) << '\n'; } return 0; }
阅读全文
1 0
- UVa1629 记忆化搜索 分格子
- uva1629 切方格使得每个方格中只有一个物品,求最少切割费用 记忆化搜索
- 蓝桥杯 历届试题 剪格子(记忆化搜索)
- JD 1550:分糖果(线性dp + 记忆化搜索)
- 记忆化搜索例题
- PKU1088---记忆化搜索
- PKU1088 记忆化搜索
- HDU1078 记忆化搜索
- HDU1501 记忆化搜索
- HDU1978 记忆化搜索
- poj1661 记忆化搜索
- zoj1107记忆化搜索
- poj1191(记忆化搜索)
- 滑雪 记忆化搜索
- hdu3779---记忆化搜索
- hdu2452---记忆化搜索
- 【记忆化搜索】滑雪
- 记忆化搜索 HDU1501
- 微信小程序自定义控件--toast(仿Android)
- python 字符串函数
- 2017/9/21
- 面向对象(继承)
- HDU 4641 至少出现K次本质不同子串数:后缀自动机
- UVa1629 记忆化搜索 分格子
- 两个有序链表序列的合并
- hdu 5726 区间gcd RMQ+二分 || 暴力枚举
- 算法训练 区间k大数查询
- HIBERNATE与 MYBATIS的对比
- 两个有序链表序列的交集
- 趋势科技面试总结
- HashMap的数据结构分析
- leetcode题目例题解析(四)