UVA12124 Assemble dichotomous answer

The original title

Ass
Ass2
Ass3

Topic effect: give your budget and all kinds of hardware to be selected to assemble the calculation, the same kind of hardware only and must purchase one of the best obtained in the case of total quality hardware to ensure adequate budget.

According bucket theory, total quality hardware to buy hardware value = Hardware Quality lowest quality.

Idea: Obviously dichotomy answer model can be half the minimum quality answers then use the check function to determine whether to meet the budget this case, because this question in N is small (<1000), so you can direct enumeration without a timeout, of course, greedy and also optimize the data structure. Another difficulty is the same type of hardware to judge, I use the Map to judge, and then store the same type of vector different types of hardware.


code show as below:

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <cstdlib>
#include <vector>
#include <map> 
#define MAXN 1007
#define INF 0x3f3f3f3f
using namespace std;
int T,n,m,tot,ans;
map<string,int> M;
struct Point { int price,quality; };
vector<Point> item[MAXN];
inline bool check(int x)
{
    int sum=0;
    for (int i=1;i<=tot;i++) {
        int fl=INF;
        for (int j=0;j<(int)item[i].size();j++) {
            if (item[i][j].quality>=x) fl=min(fl,item[i][j].price);
        }
        if (fl==INF) return false;
        sum+=fl;
    }
    return sum<=m; 
}
int main()
{
    scanf("%d",&T);
    while (T--) {
        ans=tot=0,M.clear();
        scanf("%d%d",&n,&m);
        for (int i=1;i<=n;i++) {
            string Type,Name; int p,q;
            cin>>Type>>Name>>p>>q;
            if (!M.count(Type)) M[Type]=++tot;
            item[M[Type]].push_back((Point){p,q});
        }
        /* for (int i=1;i<=tot;i++) {
            for (int j=0;j<(int)item[i].size();j++)
                printf("%d %d\n",item[i][j].price,item[i][j].quality);
            printf("\n\n");
        } */
        int left=0,right=1000000000,mid; //二分质量 
        while (left<=right) {
            mid=left+(right-left)/2;
            if (check(mid)) ans=mid,left=mid+1;
            else right=mid-1; 
        }
        printf("%d\n",ans);
        for (int i=1;i<=tot;i++) item[i].clear();
    }

    return 0;
} 

Guess you like

Origin www.cnblogs.com/zhwer/p/11313035.html