题目链接:点击这里
解题思路
此题题目描述的很简单,就是让我们用有限的预算找到最小品质因子最大的电脑组件,并且每种组件必须都要买。这种求“最小值最大”的常用方法就是二分:若猜想的答案为
x
x
,则取所有品质因子大于的组件进行组装,如果能不超过预算,则说明正确答案
>=x
>=
x
。因此,我们只需要枚举所有的品质因子,当第一个不满足题意的
x
x
出现时,则解题结束。
但需要注意,此题有时间限制,因此必须使用二分法进行,时间复杂度为。
代码实现
注意点
- 此题涉及到type,name,price,quality,比较复杂,可使用
map
进行hash,再给每个类型的组件一个vector,price和quality使用结构体进行存储。 - 需熟练使用map的各种函数。
待解决
- 在代码中已经表明,如果去掉
if(cheapest == budget)
这句话,则不能AC,显示为wrong answer
,初步猜想是由于如果品质因子太大导致sum
太大超出了int表示范围。 - 在代码中进行二分查找时,使用
int middle = (right+left)/2
则显示超时,为什么? - 可将质量因子先排好序,再用二分查找进行枚举,可能会更快。
代码示例
#include <iostream>
#include <vector>
#include <map>
using namespace std;
const int maxn = 1000 + 10;
int cnt = 0;
int n; //预算和组件数目
int budget;
struct Compont {
int price;
int quality;
};
std::vector<Compont> comp[maxn]; //每一项都是vector的数组
std::map<string, int> ID;
int convert(string type)
{
if (!ID.count(type))
{ //如果还没有这个类型的组件
ID[type] = cnt++;
}
return ID[type];
}
//看品质不小于q的组件是否能在预算范围内组装
bool judge(int q)
{
int sum = 0;
for (int i = 0 ; i < cnt; i++)
{
int cheapest = budget;
int m = comp[i].size();
for (int j = 0; j < m; j++)
{
if (comp[i][j].quality >= q)
cheapest = min(cheapest, comp[i][j].price);
}
sum += cheapest;
//若没加这一句,则不能AC
if(cheapest == budget)
return false;
if (sum > budget)
return false;
}
return true;
}
int main()
{
int N;
cin >> N;
while (N--)
{
cin >> n >> budget;
cnt = 0;
for (int i = 0 ; i < n ; i++)
{
comp[i].clear();
}
ID.clear();
int maxq = 0;
for (int i = 0 ; i < n; i++)
{
string type, name;
int p, q;
cin >> type >> name >> p >> q;
maxq = max(maxq, q);
comp[convert(type)].push_back((Compont) {p, q});
}
//使用二分法来加快速度
int left = 0,right = maxq;
while (left < right)
{
int middle = (right+left+1)/2 ;
//int middle = (right+left)/2 ; 为什么不可以?
if (judge(middle))
left = middle;
else
{
right = middle - 1;
}
}
cout << left << endl;
}
return 0;
}
欢迎关注我的个人博客。