題意:
讓你去購買不同總類的配件個一個,配件總數爲n,購買的配件總價格不能超過b,且使得所購買的配件中的質量係數中最小的最大
分析:
最小最大的問題,二分枚舉能不能構成不小於k的質量係數,若能構成則ans >= k,否則ans < k.
Code:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <map>
#include <vector>
using namespace std;
#define MAXCHAR 20 + 10
#define MAXN 1000 + 10
#define INF 0x3f3f3f3f
typedef struct COMP {
int q, p;
}Comp;
map<string, int> k;
vector<Comp> components[MAXN];
char k_name[MAXCHAR], name[MAXCHAR];
int k_idx, s[MAXN];
int get_k_idx(char *str)
{
string tmp;
tmp.clear();
for(int i = 0; i < strlen(str); i ++) {
tmp += str[i];
}
map<string, int>::iterator it;
it = k.find(tmp);
if( it != k.end() ) {
return it->second;
}
k.insert(map<string, int>::value_type(tmp, k_idx));
return k_idx ++;
}
bool valid(int cur_q, int n, int price)
{
int sum = 0;
for(int i = 1; i < k_idx; i ++) {
int p = INF;
for(int j = 0; j < components[i].size(); j ++) {
if( components[i][j].q < cur_q ) {
continue;
}
p = min(p, components[i][j].p);
}
if( INF == p ) {
return false;
}
sum += p;
}
if( sum > price ) {
return false;
}
return true;
}
int main(int argc, char **argv)
{
#ifndef ONLINE_JUDGE
freopen("test.in", "r", stdin);
#endif
Comp tmp;
int cas, n, b, max_q;
scanf("%d", &cas);
for( ; cas; cas --) {
scanf("%d %d", &n, &b);
k.clear();
for(int i = 1; i <= n; i ++) {
components[i].erase(components[i].begin(), components[i].end());
}
max_q = 0, k_idx = 1;
for(int i = 1; i <= n; i ++) {
scanf("%s %s %d %d", k_name, name, &tmp.p, &tmp.q);
int k = get_k_idx(k_name);
components[k].push_back(tmp);
max_q = max(max_q, tmp.q);
}
int L = 0, R = max_q, M, ans = 0;
while( L < R ) {
M = (L+R)/2;
if( true == valid(M, n, b) ) {
ans = max(ans, M);
L = M+1;
continue;
}
R = M;
}
if( true == valid(max_q, n, b) ) {
ans = max(ans, max_q);
}
printf("%d\n", ans);
}
return 0;
}