题意:
有一个人有b元,要去买零件,有n个零件,零件有不同的种类,名称,价格,质量,要求每种零件买一个,不超过b元钱,让最差质量尽量好,问最差质量是多少。
题解
最小值最大问题,所以二分答案,再去判断是否满足题目要求的每种类型都要选,并不超过所给的金额,可知二分答案的范围是左闭右开 ,ans>=x,否则ans<x。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> #include <vector> #include <cmath> #include <set> #include <map> using namespace std; int t; int cnt; struct node { int m,p; }; map<string,int> mp; //为每一种配件顺序记录编号 int id(string s) { if(!mp.count(s)) mp[s]=cnt++; return mp[s]; } int a,b;//配件数和预算 vector<node> comp[1005]; //判断二分的品质因子是否符合 bool ok(int k) { int sum=0; for(int i=0;i<cnt;i++)//各个种类 { int cheapest=1e9+1;//找到满足不小于k的最小值 int si=comp[i].size(); for(int j=0;j<si;j++) { if(comp[i][j].p>=k) //因为假设的最小因子是k,所以小于k的都不符合 cheapest=min(cheapest,comp[i][j].m); } if(cheapest==1e9+1) return false;//k太大 取不到配件 不满足 sum+=cheapest;//选择第i种配件 if(sum>b) return false; //超出预算 } //printf("sum %d mid %d\n",sum,k); return true; } int main() { scanf("%d",&t); while(t--) { scanf("%d%d",&a,&b); for(int i=0;i<a;i++) comp[i].clear(); mp.clear(); cnt=0;//记录配件的种类 int mx=0;//记录最大的品质因子 while(a--) { char type[30],name[30]; int p,m; scanf("%s%s%d%d",type,name,&m,&p); mx=max(mx,p); comp[id(type)].push_back((node){m,p}); } //二分 int l=0,r=mx,mid; while(l<r) { //printf("l %d r %d\n",l,r); mid=l+(r-l+1)/2;//因为是左闭右开 if(ok(mid)) l=mid; else r=mid-1; } printf("%d\n",l); } return 0; } 最后附上二分的常用边界写法 以避免TLE
