题目链接:
C - Grid of Lamps
Memory Limit: 0KB
输入
The first line of input contains an integer T ≤ 100 denoting the number of test-cases. Each test-case
begins with two integers M and N, both in the interval [1, 1000], determining the number of rows and
columns of the grid respectively. The next two lines give the luminosities, the first for rows (M values)
and the second for columns (N values).
输出
For each test-case, on a single line, output the minimum conceivable number of lighted lamps.
样例
sample input
3
2 2
2 0
0 2
1 4
2
1 0 1 1
2 4
3 1
0 2 1 2sample output
3
3
5
题意
在n*m行的矩阵中
给你每行至少要亮的灯泡和每列至少要亮的灯泡,问至少有多少个灯泡要亮。
题解
在交叉点放越多的灯泡,就能使灯泡数越少。
题目相当于是问现在你能够用每一列的值去消行的值(每一列只能消一次行,剩余的无法消的后面也不能用!),问最多能消掉多少数,贪心的,我们每一次肯定优先消掉最大的k行,因为最大的行是最有可能消不完的。
用一个优先队列来维护,或者消完一次行,就对行重新排一下序也可以。
代码
#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
const int maxn = 1010;
int a[maxn], b[maxn];
int n, m;
int main() {
int tc;
scanf("%d", &tc);
while (tc--) {
scanf("%d%d", &n, &m);
int sum = 0;
for (int i = 0; i < n; i++) scanf("%d", &a[i]), sum += a[i];
for (int j = 0; j < m; j++) scanf("%d", &b[j]), sum += b[j];
int cnt = 0;
priority_queue<int> pq;
for (int i = 0; i < n; i++) pq.push(a[i]);
int st = 0;
vector<int> tmp;
while (st < m&&pq.top()) {
tmp.clear();
while (!pq.empty()&&pq.top() && b[st]) {
cnt++;
b[st]--;
tmp.push_back(pq.top() - 1);
pq.pop();
}
for (int i = 0; i < tmp.size(); i++) {
pq.push(tmp[i]);
}
st++;
}
printf("%d
", sum - cnt);
}
return 0;
}