题意:你有b元钱,想要组装一台电脑,给出n个配件各自的种类、品质银子和价格,要求每种类型的配件各买一个,总价格不超过b,且“品质最差配件”的品质因子应该尽量大
二分 品质因子
每次在 每个种类配件中 选择大于等于改品质因子X 的最便宜的配件,如果加起来不超过b表示可以,否则要选更小的品质因子
代码:
ac代码:
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
#include <stack>
#include <map>
#include <vector>
using namespace std;
const int inf =2147483640;
struct node
{
int q;
int p;
bool operator<(const node &b)const
{
return q<b.q;
}
};
int min(int a,int b)
{return a<b?a:b;}
map <string,int> uu;
vector<node> tm[1005];
vector<node>::iterator it;
node point[1005];
int cun=0;
int n,b;
int main()
{
int ok(int x);
int t;
cin>>t;
while(t--)
{
int i;
for (i=1;i<=n;i++)
tm[i].clear();
uu.clear();
scanf("%d%d",&n,&b);
char tmp[35];
char type[35];
int minn=inf;
int maxx=0-1;
cun=0;
for (i=1;i<=n;i++)
{
scanf("%s %s %d %d",type,tmp,&point[i].p,&point[i].q);
string ss=type;
if (uu.find(ss)==uu.end())
uu[type]=++cun;
int id=uu[type];
tm[id].push_back(point[i]);
if (point[i].q<minn)
minn=point[i].q;
if (point[i].q>maxx)
maxx=point[i].q;
}
for (i=1;i<=cun;i++)
sort(tm[i].begin(),tm[i].end());
int l=minn;
int r=maxx;
while(l<=r)
{
int mid=(l+r)/2;
if (r-l==0) //只有一个待选答案
break;
if (r-l==1)//2选1
{
if (!ok(r)) r=l;
break;
}
if (ok(mid))//不断逼近,
l=mid; //mid可能合法
else
r=mid-1; //mid一定不合法
}
printf("%d\n",r);
}
return 0;
}
int ok(int x)
{
int sum=0;
int i;
node tmp; tmp.q=x;
for (i=1;i<=cun;i++)
{
it=lower_bound(tm[i].begin(),tm[i].end(),tmp);
if (it==tm[i].end()) return 0; //****找不到品质大于等于X的配件***不要忘了判断找不到的情况
int cheapest=it->p;
for (it;it!=tm[i].end();it++)
{
cheapest=min(cheapest,it->p);
}
sum+=cheapest;
}
if (sum>b)
return 0;
else
return 1;
}