Uva 12382 题目链接:点击打开链接
ZOJ 3732题解:点击打开链接
Uva12382
题意:
给定n*m的地板,每个地板上有一盏灯,要么亮要么暗。
下面n个数字表示每行至少亮的灯盏数
下面m个数字表示每列至少亮的灯盏数
求:开始灯都是暗的,最少点亮几盏灯能满足上述条件
思路:
先给行和列大到小排序,然后每次用行减掉列。减完后再排个序即可。
即:实时排序。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
const int N = 1005;
typedef long long ll;
int a[N], b[N];
bool cmp(const int x, const int y) {
return x>y;
}
int main() {
int T, n, m;
scanf("%d", &T);
while(T-- > 0) {
scanf("%d%d", &n, &m);
int suma = 0, sumb = 0;
for(int i = 0; i < n; i ++) {
scanf("%d", &a[i]);
suma += a[i];
}
for(int i = 0; i < m; i ++) {
scanf("%d", &b[i]);
sumb += b[i];
}
int ans = 0;
if(suma < sumb) {
for(int i = 0; i < n; i ++) {
sort(b, b+m, cmp);
for(int j = 0; j < m && a[i]; j ++) {
if(b[j]) {
ans ++;
a[i]--;
b[j]--;
suma --;
sumb --;
} else break;
}
}
} else {
for(int j = 0; j < m; j ++) {
sort(a, a+n, cmp);
for(int i = 0; i < n && b[j]; i ++) {
if(a[i]) {
ans ++;
a[i]--;
b[j]--;
suma --;
sumb --;
} else break;
}
}
}
printf("%d\n", ans + suma + sumb);
}
return 0;
}