UVA12124 Assemble 二分答案

原题

Ass
Ass2
Ass3

题目大意:给出你的预算和各类待选硬件来组装计算,同种类的硬件只需且必须选购一种,在保证预算足够的情况下求出最优的合计硬件质量。

根据木桶原理,合计硬件质量 = 所选购硬件中数值最低质量的硬件质量。

思路:很显然的二分答案模型,可以将最低质量二分答案后再用check函数判断该情况下是否满足预算要求,由于本题中N较小(<1000),所以可以直接枚举而不超时,当然亦可用贪心和数据结构优化。还有一个难点是同一类别的硬件的判断,我这里用了Map进行判断,再用vector存放同一类硬件的不同型号。


代码如下:

#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;
} 

猜你喜欢

转载自www.cnblogs.com/zhwer/p/11313035.html
今日推荐