Color Rows and Columns§
贪心的方法不好想。
不过题目给定数据范围很小。
考虑能不能
DP。发现每一个矩形可能产生的贡献并不多,最多 \(a_i+b_i\) ,显然可以模拟贪心过程处理出来。
每次选择较短的边涂颜色,长边长度减一,持续这个操作就行。
\(cnt_{i,k}\) 表示第
i个矩形,贡献为k时需要的成本。处理出来这个之后,就是一个典型的
01背包问题了。#include <bits/stdc++.h> #define int long long void solve() { int n, k; std::cin >> n >> k; std::vector<std::vector<int>> cnt(n, std::vector<int>(201, 1e9)); for (int i = 0; i < n; i++) { int x, y; std::cin >> x >> y; if (x > y) std::swap(x, y); int mid = 0, idx = 1; cnt[i][0] = 0; while (y > 0) { mid += x; cnt[i][idx++] = mid; y--; if (x > y) std::swap(x, y); } } std::vector<int> dp(k + 1, 1e9); dp[0] = 0; for (int i = 0; i < n; i++) { for (int j = k; j >= 0; j--) { for (int z = 0; z <= j; z++) { dp[j] = std::min(dp[j], cnt[i][z] + dp[j - z]); } } } if (dp[k] < 1e9) std::cout << dp[k] << '\n'; else { std::cout << -1 << '\n'; } } signed main() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); int t; std::cin >> t; while (t--) { solve(); } return 0; }