1. 程式人生 > >3971 -二分答案(最小值最大化)

3971 -二分答案(最小值最大化)

  • Assemble

  • 題意:你有b塊錢,想要組裝一臺電腦。給出n個配件格子的種類,品質因子和價格,
  • 要求每種型別的配件各買一個。總價格不超過b,且品質最差的配件的品質因子儘量大。
  • 思路:求出單個的最大值,這是二分答案的上界,0為下界,求一個最小值的最大化
  • 所以只要check滿足就要把L去接近R,最後輸出第一個不滿足的前一個
  • #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    string type,name;
    int pr,qa,m,n,t;
    int l,r,cnt;
    #define maxn 1555
    map<string,int>mmp;
    struct node
    {
        int prize,q;
    };
    vector<node>num[maxn];
    bool check(int x)
    {
        ll sum=0;
        for(int i=1; i<=cnt; i++)
        {
            int len=num[i].size(),minn=m+10;
            for(int j=0; j<len; j++)
            {
                if(num[i][j].q>=x)
                    minn=min(minn,num[i][j].prize);
            }
            sum+=minn;
            if(sum>m)return 0;
        }
        return 1;
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin>>t;
        while(t--)
        {
            for(int i=1; i<=cnt; i++)
                num[i].clear();
            cnt=r=l=0;
            mmp.clear();
            cin>>n>>m;
            for(int i=0; i<n; i++)
            {
                cin>>type>>name>>pr>>qa;
                if(mmp[type]==0)
                    mmp[type]=++cnt;
                num[cnt].push_back(node{pr,qa});
                r=max(r,qa);
            }
            while(l<r)
            {
                int mid=(l+r+1)/2;
                if(check(mid))l=mid;
                else r=mid-1;
            }
            cout<<r<<endl;
        }
        return 0;
    }