1 条题解
-
0
自动搬运
来自洛谷,原作者为

Usada_Pekora
兎田ぺこら/大傻Peko_Official/AFO搬运于
2025-08-24 21:34:25,当前版本为作者最后更新于2021-11-24 12:39:44,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
题意:纵横划分区域,使得除去某一区域的值后其他区域的和不超过 。
思路:用 dfs 划分区域,如果沿着当前轴划分是可行的,那么再对划分后的区域进行 dfs 。
但是这样做的时间成本是很高的, 因为这种做法对同一区间做了重复的计算,这个时候就考虑用数组记录某一区间的最优值,在产生重复计算时直接调用即可。 设 表示 到 的最优划分,则答案是 。
代码如下。
#include<bits/stdc++.h> #define min(a,b) (a<b?a:b) #define max(a,b) (a>b?a:b) using namespace std; typedef pair<int,int> pii; inline int read(){ int x = 0;char ch = getchar(); while(ch < '0' || ch > '9'){ch = getchar();} while(ch >= '0' && ch <= '9'){x = (x<<1)+(x<<3)+(ch^48);ch = getchar();} return x; } int n,m,u,a[35][35],sum = 0,s[35][35]; pii f[35][35][35][35]; #define calc(x1,y1,x2,y2) (s[x2][y2]+s[x1-1][y1-1]-s[x1-1][y2]-s[x2][y1-1]) inline pii dfs(int x1,int y1,int x2,int y2,int all){ if(f[x1][y1][x2][y2].first) return f[x1][y1][x2][y2]; if(x1 == x2 && y1 == y2) return pii{1,u-(sum-all)}; pii t;t.first = 1,t.second = u-(sum-all); for(register int i = y1;i < y2;++i){ int s1 = calc(x1,y1,x2,i),s2 = calc(x1,i+1,x2,y2); if(sum-s1 <= u && sum-s2 <= u){ pii p1 = dfs(x1,y1,x2,i,s1),p2 = dfs(x1,i+1,x2,y2,s2); if(p1.first+p2.first > t.first)t.first = p1.first+p2.first,t.second = min(p1.second,p2.second); else if(p1.first+p2.first == t.first) t.second = max(t.second,min(p1.second,p2.second)); } } for(register int i = x1;i < x2;++i){ int s1 = calc(x1,y1,i,y2),s2 = calc(i+1,y1,x2,y2); if(sum-s1 <= u && sum-s2 <= u){ pii p1 = dfs(x1,y1,i,y2,s1),p2 = dfs(i+1,y1,x2,y2,s2); if(p1.first+p2.first > t.first)t.first = p1.first+p2.first,t.second = min(p1.second,p2.second); else if(p1.first+p2.first == t.first) t.second = max(t.second,min(p1.second,p2.second)); } } return f[x1][y1][x2][y2] = t; } int main(){ n = read(),m = read(),u = read(); for(register int i = 1;i <= n;++i) for(register int j = 1;j <= m;++j) a[i][j] = read(),sum += a[i][j]; for(register int i = 1;i <= n;++i) for(register int j = 1;j <= m;++j) s[i][j] = s[i][j-1]+s[i-1][j]-s[i-1][j-1]+a[i][j]; pii ans = dfs(1,1,n,m,sum); printf("%d %d",ans.first,ans.second); return 0; }
- 1
信息
- ID
- 1126
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 4
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者