算法竞赛入门经典训练指南打卡
题目链接:UVALive 3971
思路
使用二分查找的方法,假设答案为q,每个类型配件中找到价格最小且品质因子大于等于q的配件,查看加起来的价格是否不超过预算即可
思路简单,具体细节看代码注释
代码如下:
#include <iostream>
#include <vector>
#include <map>
#define max_n 1005
using namespace std ;
struct Component{
int price ;
int quality ;
};
map<string , int> id ; //映射配件类型
vector<Component> comp[max_n] ; //存储配件信息
int cnt , n , money ; //配件的类型数,个数,和预算
int ID(string s){
if (!id.count(s))
id[s] = cnt ++ ; //如果没有该类型,添加该类型
return id[s] ; //返回该类型对应的id
}
bool OK(int q){
int sum = 0 ;
for(int i = 0 ; i < cnt ; ++ i){
int cheapest = money + 1 , m = comp[i].size() ;
for(int j = 0 ; j < m ; ++ j)
if(comp[i][j].quality >= q)
cheapest = min(cheapest , comp[i][j].price) ; //遍历该类型配件中所有品质因子大于q的配件,查看价格
if(cheapest == money + 1) //如果所有价格高于预算,不能组装成功
return false ;
sum += cheapest ; //如果可以拿来组装,加上当前价格
if(sum > money)
return false ; //查看最后的总价格是否大于预算,如果大于无法组装成功
}
return true ;
}
int main(){
int t ;
cin >> t ;
while (t --){
cin >> n >> money ;
cnt = 0 ;
id.clear() ;
for(int i = 0 ; i < n ; ++ i)
comp[i].clear() ;
int maxq = 0 ; //初始化所有变量和数组
while (n --){
string type , name ;
Component x ;
cin >> type >> name >> x.price >> x.quality ;
comp[ID(type)].push_back(x) ; //将该组件分类型存放在一起
maxq = max(maxq , x.quality) ; //找到最大的品质因子
}
int L = 0 , R = maxq ;
while (L < R){ //二分查找找到最小的品质因子的最大值
int M = L + (R - L + 1) / 2 ;
if(OK(M))
L = M ;
else
R = M - 1 ;
}
cout << L << endl ;
}
return 0 ;
}