题意:有一个n行m列(1<=n, m<=20)的网格蛋糕上有一些樱桃。每次可以用一刀沿着网格线把蛋糕切成两块,并且只能够直切不能拐弯。要求最后每一块蛋糕上恰好有一个樱桃,且切割线总长度最小。

分析:dp[up][down][left][right]表示上下左右界分别为up,down,left,right的蛋糕,为了使最后每一块蛋糕上恰好有一个樱桃,切割线的最小总长度。

#pragma comment(linker, "/STACK:102400000, 102400000")
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<cmath>
#include<iostream>
#include<sstream>
#include<iterator>
#include<algorithm>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<deque>
#include<queue>
#include<list>
#define Min(a, b) ((a < b) ? a : b)
#define Max(a, b) ((a < b) ? b : a)
const double eps = 1e-8;
inline int dcmp(double a, double b){
if(fabs(a - b) < eps) return 0;
return a > b ? 1 : -1;
}
typedef long long LL;
typedef unsigned long long ULL;
const int INT_INF = 0x3f3f3f3f;
const int INT_M_INF = 0x7f7f7f7f;
const LL LL_INF = 0x3f3f3f3f3f3f3f3f;
const LL LL_M_INF = 0x7f7f7f7f7f7f7f7f;
const int dr[] = {0, 0, -1, 1, -1, -1, 1, 1};
const int dc[] = {-1, 1, 0, 0, -1, 1, -1, 1};
const int MOD = 1e9 + 7;
const double pi = acos(-1.0);
const int MAXN = 20 + 10;
const int MAXT = 10000 + 10;
using namespace std;
int pic[MAXN][MAXN];
int dp[MAXN][MAXN][MAXN][MAXN];
int getNum(int up, int down, int left, int right){//求蛋糕上的樱桃数
int ans = 0;
for(int i = up; i <= down; ++i){
for(int j = left; j <= right; ++j){
if(pic[i][j]) ++ans;
}
}
return ans;
}
int dfs(int num, int up, int down, int left, int right){//num蛋糕上的樱桃数
if(dp[up][down][left][right] != -1) return dp[up][down][left][right];
if(num == 1) return dp[up][down][left][right] = 0;
int ans = INT_INF;
for(int i = up; i < down; ++i){//枚举分割线,i为第i行下面的分隔线,横切
int tmp = getNum(up, i, left, right);//切割完上半部分蛋糕上的樱桃数
if(tmp >= 1 && tmp < num){//被切割成的两块蛋糕上都有樱桃
int x = dfs(tmp, up, i, left, right);
int y = dfs(num - tmp, i + 1, down, left, right);
ans = Min(ans, x + y + right - left + 1);
}
}
for(int i = left; i < right; ++i){//竖切
int tmp = getNum(up, down, left, i);
if(tmp >= 1 && tmp < num){
int x = dfs(tmp, up, down, left, i);
int y = dfs(num - tmp, up, down, i + 1, right);
ans = Min(ans, x + y + down - up + 1);
}
}
return dp[up][down][left][right] = ans;
}
int main(){
int n, m, k;
int kase = 0;
while(scanf("%d%d%d", &n, &m, &k) == 3){
memset(pic, 0, sizeof pic);
memset(dp, -1, sizeof dp);
for(int i = 0; i < k; ++i){
int x, y;
scanf("%d%d", &x, &y);
pic[x][y] = 1;
}
printf("Case %d: %d\n", ++kase, dfs(k, 1, n, 1, m));
}
return 0;
}

  

最新文章

  1. linux 字符设备驱动写法
  2. 老司机学Xamarin系列总目录
  3. JS_MediaPlayer类
  4. swift_初始化器的使用
  5. svn做目录访问控制(AuthzSVNAccessFile)
  6. uglifyjs使用
  7. Unity3d:megaFierstext(翻书效果插件)
  8. svn: E230001: Server SSL certificate verification failed
  9. Poj 1953 World Cup Noise之解题报告
  10. log4j 1.2配置(转载)
  11. 如何捕获winform程序全局异常?(续)
  12. JDK 安装过程
  13. Python 面向对象之一
  14. 概括一下nodejs
  15. 运维技巧-Nginx日志格式
  16. 【Python实践-1】求一元二次方程的两个解
  17. 翻译:SET Variable(已提交到MariaDB官方手册)
  18. [mvc] 简单的forms认证
  19. pytorch学习资料链接
  20. delphi try except语句 和 try finally语句用法以及区别

热门文章

  1. P1062 最简分数
  2. Zabbix——自动监控
  3. LOJ #10002. 喷水装置
  4. 十五、React:简单点餐实例:知识点,html解析写法
  5. 吴裕雄 Bootstrap 前端框架开发——Bootstrap 字体图标(Glyphicons):glyphicon glyphicon-music
  6. HttpClient测试
  7. &lt;深入理解redis&gt;读书笔记
  8. [强网杯 2019]Upload
  9. IP地址 网络地址 子网掩码
  10. 小米百元NFC智能神器来了:必成爆款!