题意:
有b块钱,n个配件及其种类,质量,价格,让你每种类型的配件各买一个,总价不超过b元,让品质最差的配件质量最好,求最小品质的质量最大值
思路:
二分最小质量的最大值,再用贪心的思想判断该质量是否可行,即排序每种配件的价格,判断时按价格从低到高扫描,选择到符合该质量的即可。
代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int N = 1005;
const int M = 25;
struct Comp {
char name[M];
int price;
int quality;
}s[N][N];
int cnt, sum, same[N];
char str[N][M], type[M];
int cmp(const Comp& x, const Comp& y) {
return x.price < y.price;
}
int find(char type[]) {
int i;
for (i = 0; i < cnt; i++)
if (!strcmp(type, str[i]))
return i;
strcpy(str[cnt],type);
return cnt;
}
int judge(int Min) {
int tmp = 0,i,j;
for (i = 0; i < cnt; i++) {
int flag = 1;
for (j = 0; j < same[i]; j++) {
if (s[i][j].quality >= Min) {
flag = 0;
tmp += s[i][j].price;
break;
}
}
if (flag || tmp > sum) return false;
}
return true;
}
int main() {
Comp start;
int cas, n, cur, L, R;
scanf("%d", &cas);
while (cas--) {
memset(s, 0, sizeof(s));
memset(same, 0, sizeof(same));
memset(str, 0, sizeof(str));
cnt = L = R = 0;
scanf("%d%d", &n, &sum);
for (int i = 0; i < n; i++) {
scanf("%s%s%d%d", type, start.name, &start.price, &start.quality);
if (start.quality > R)
R = start.quality;
cur = find(type);
s[cur][same[cur]++] = start;
if (cur == cnt) cnt++;
}
for (int i = 0; i < cnt; i++)
sort(s[i], s[i] + same[i], cmp);
int mid;
while (L < R) {
mid = (L + R) / 2;
if (L == mid) break;
if (judge(mid))
L = mid;
else
R = mid;
}
if (judge(mid + 1)) mid++;
printf("%d\n", mid);
}
return 0;
}