LRJ入门经典-0903切蛋糕305
原题
LRJ入门经典-0903切蛋糕305 |
难度级别:B; 运行时间限制:1000ms; 运行空间限制:256000KB; 代码长度限制:2000000B |
试题描述
|
输入
|
第一行包含三个正整数n,m和k(1<=n,m<=20),k表示樱桃数量
以下k行每行包含两个正整数,表示每个樱桃所在的行和列 |
输出
|
输出最优方案的切割边数
|
输入示例
|
3 4 3
1 2 2 3 3 2 |
输出示例
|
5
|
分析
第一眼看到“(1<=n,m<=20)”就想到了DFS,但普通的DFS显而易见会超时,只能用记忆化搜索了。
dp[i1][j1][i2][j2]代表坐标为(i1,j1)的点与坐标为(i2,j2)的点围成的长方形蛋糕,将其切成蛋糕上有且仅有一个樱桃时的最小切割边数。(初值为-1)
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | #include<cstdio> #include<algorithm> #include<cstring> using namespace std; int n,m,k,a[21][21],dp[21][21][21][21]; inline int check( int x1, int y1, int x2, int y2) { int sum=0; for ( int i=x1;i<=x2;i++) for ( int j=y1;j<=y2;j++) if (a[i][j]) sum++; return sum; } inline int dfs( int x1, int y1, int x2, int y2) { int &d=dp[x1][y1][x2][y2]; if (d>-1) return d; int sum=check(x1,y1,x2,y2); if (sum==0) return d=1000000; if (sum==1) return d=0; int minn=1000000; for ( int i=x1;i<x2;i++) minn=min(minn,dfs(x1,y1,i,y2)+dfs(i+1,y1,x2,y2)+(y2-y1+1)); for ( int i=y1;i<y2;i++) minn=min(minn,dfs(x1,y1,x2,i)+dfs(x1,i+1,x2,y2)+(x2-x1+1)); return d=minn; } int main() { scanf ( "%d%d%d" ,&n,&m,&k); for ( int i=1;i<=k;i++) { int x,y; scanf ( "%d%d" ,&x,&y); a[x][y]=1; } memset (dp,-1, sizeof (dp)); printf ( "%d" ,dfs(1,1,n,m)); } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】