【UVA12124】Assemble

題面

  Recently your team noticed that the computer you use to practice for programming contests is not good enough anymore. Therefore, you decide to buy a new computer.
  To make the ideal computer for your needs, you decide to buy separate components and assemble the computer yourself. You need to buy exactly one of each type of component.
  The problem is which components to buy. As you all know, the quality of a computer is equal to the quality of its weakest component. Therefore, you want to maximize the quality of the component with the lowest quality, while not exceeding your budget.

題意

  有n 個物品,每個物品有四個屬性:種類Type ,名稱Name ,價格P 和品質Q
  現在要在每一種物品中各選出一個,滿足kPkB ,設其中Q 的最小值爲x ,求所有方案中最大的x
  100組數據,n1000B109P106Q109

解法

二分:
  話說這道題是一個字符串處理題……
  看到最小值最大,很容易想到二分:
  上界R=Qmax ,下界L=0 ,對於中值lim ,在每一種物品中刪去Q 值小於lim 的部分,然後在剩下的部分中找到P 值最小的一個,累加起來,判斷與B 的關係即可
  現在關鍵就是找出有多少種物品和每一種物品有多少個:
  這裏使用map 來記錄種類,用vector 來記錄編號,詳細過程看代碼……所以說這一題就是一個字符串處理題……

複雜度

O(nlogR

代碼

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<vector>
#include<map>
#define Lint long long int
using namespace std;
const int INF=1e9+7;
const int MAXN=1010;
struct node
{
    Lint p,q;
};
int T,n,cnt;
Lint b;
map<string,int> id;
vector<node> t[MAXN];
bool check(Lint lim)
{
    Lint ret=0,tmp;
    for(int i=1,x;i<=cnt;i++)
    {
        x=t[i].size()-1,tmp=INF;
        for(int j=0;j<=x;j++)
            if( t[i][j].q>=lim )   tmp=min( tmp,t[i][j].p );
        ret+=tmp;
    }
    return ret<=b;
}
int main()
{
    string type,name;
    Lint x,y,l,r;
    scanf("%d",&T);
    while( T-- )
    {
        l=r=cnt=0;
        scanf("%d%lld",&n,&b);
        for(int i=1;i<=n;i++)
        {
            cin>>type>>name;
            scanf("%lld%lld",&x,&y);
            if( !id[type] )   id[type]=++cnt;
            t[id[type]].push_back( (node){ x,y } );
            r=max( r,y );
        }
        while( l<=r )
        {
            int mid=(l+r)/2;
            if( check( mid ) )   l=mid+1;
            else   r=mid-1;
        }
        printf("%lld\n",l-1);
        id.clear();
        for(int i=1;i<=cnt;i++)   t[i].clear();
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章