题目:Assemble
思路:
贪心+二分。
二分最大的最小品质值x。
每次选品质值超过x的价格最低的配件。
注意:
1、多组数据,初始化时不能忘记minw和maxw。
2、二分边界不能写错。
3、如果在同一种类中无法找到可以买的配件,也作不可能处理。
代码:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <stack>
#include <queue>
#include <deque>
#include <set>
#include <cstring>
#include <map>
using namespace std;
#define maxn 1000
#define maxb 1000000000
struct ob {
int w,c;
ob() {}
ob(int w_,int c_) {
w=w_,c=c_;
}
};
int n,b;
map<string,int> mp;
vector<ob> vec[maxn+5];
int cnt;
int minw=(1<<30),maxw=0;
void init() {
for(int i=1; i<=maxn; i++) {
vec[i].clear();
}
mp.clear();
cnt=0;
minw=(1<<30),maxw=0;
}
void readin() {
scanf("%d%d",&n,&b);
for(int i=1; i<=n; i++) {
string x,y;
cin>>x>>y;
if(!mp.count(x)) mp[x]=++cnt;
int c,w;
scanf("%d%d",&c,&w);
minw=min(minw,w);
maxw=max(maxw,w);
vec[mp[x]].push_back(ob(w,c));
}
}
bool judge(int x) {
int s=0;
bool flag;
for(int i=1; i<=cnt; i++) {
flag=false;
int minc=(1<<30);
for(int j=0; j<vec[i].size(); j++) {
if(vec[i][j].w>=x&&minc>vec[i][j].c) {
minc=vec[i][j].c;
flag=true;
}
}
s+=minc;
if(s>b||!flag) return false;
}
return true;
}
int main() {
int T;
scanf("%d",&T);
while(T--) {
init();
readin();
int l=minw,r=maxw;
while(l+1<r) {
int mid=(l+r)/2;
if(judge(mid)) l=mid;
else r=mid;
}
if(judge(l+1)) l++;
printf("%d\n",l);
}
return 0;
}