CF2000F Color Rows and Columns
题解
知识点:贪心、背包dp。
先考虑一个矩形的情况:
- 若是方形,行列交替染色最优。
- 若不是方形,选行列中较小的一侧染色,直到变为方形。
因此,我们可以根据上面的结论预处理 ,表示第 个矩形贡献为 的最小花费。
现在考虑多个矩形的情况,显然是一个分组背包问题。每个矩形为一个组,第 个矩形有 个项(包括不选) ,第 项贡献为 花费是 ,每组只能选一个。
我们设 表示前 个矩形贡献为 时的最小花费。特别地,根据题意我们采用一个技巧,定义 表示前 个矩形贡献至少为 时的最小花费。
计算花费有两种方法,打表法和刷表法,前者寻找前导状态更新当前状态,后者寻找后继状态更新后继状态,采用上述技巧后更适合采用刷表法。打表法实现和效率都会更复杂,因为 的前导状态将变为 ,而非 个。
初始化正无穷, ,转移方程如下:
for (int i = 1;i <= n;i++) { for (int j = 0;j <= k;j++) { for (int id = 0;id <= a[i] + b[i];id++) { f[i][min(k, j + id)] = min(f[i][min(k, j + id)], f[i - 1][j] + c[i][id]); } } }
此外,如果采用单行滚动数组优化,第二层循环应变为逆序,且第二层和第三层循环不能交换。
当然,也可以采用两行数组实现滚动数组,更方便。
时间复杂度
空间复杂度
代码
#include <bits/stdc++.h> using namespace std; using ll = long long; int a[1007], b[1007]; int c[1007][207]; // 第 i 个矩形贡献为 j 的最小花费 int f[1007][107]; // 前 i 个矩形贡献为 j 的最小花费,分组背包 bool solve() { int n, k; cin >> n >> k; for (int i = 1;i <= n;i++) { cin >> a[i] >> b[i]; int delta = abs(a[i] - b[i]); // 短边先填,直至方形 for (int j = 1;j <= delta;j++) c[i][j] = c[i][j - 1] + min(a[i], b[i]); // 方形行列交替填 for (int j = delta + 1; j <= a[i] + b[i];j++) c[i][j] = c[i][j - 1] + min(a[i], b[i]) - (j - delta) / 2; } for (int i = 0;i <= n;i++) for (int j = 0;j <= k;j++) f[i][j] = 1e9; // 建议刷表法,因为 fi,k 表示前 i 个矩形贡献 >= k 的最小花费,填表法在 fi,k 的处理会更复杂,效率也更低 f[0][0] = 0; for (int i = 1;i <= n;i++) { for (int j = 0;j <= k;j++) { for (int id = 0;id <= a[i] + b[i];id++) { f[i][min(k, j + id)] = min(f[i][min(k, j + id)], f[i - 1][j] + c[i][id]); } } } cout << (f[n][k] > 1e8 ? -1 : f[n][k]) << '\n'; return true; } int main() { std::ios::sync_with_stdio(0), std::cin.tie(0), std::cout.tie(0); int t = 1; cin >> t; while (t--) { if (!solve()) cout << -1 << '\n'; } return 0; }
本文来自博客园,作者:空白菌,转载请注明原文链接:https://www.cnblogs.com/BlankYang/p/18427520
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧