UVALive 3971-Assemble- 最小值最大化(二分)

来源:互联网 发布:linux 关闭网络接口 编辑:程序博客网 时间:2024/04/29 04:31

题意:你有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; }


0 0
原创粉丝点击