您的位置:首页 > 其它

HDU-Fish买电脑 二分查找

2012-08-12 20:06 288 查看
这题可以用二分枚举答案来求解,每次枚举一个答案时我们总是选取满足要求的每个零件的价格最小者,如果金钱能够满足的话就枚举一个更大的质量,这里最好将质量离散化,这样就能枚举每个点都用相应的品质对应。

代码如下:

#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <map>
using namespace std;

map<int,int>mp;

int fee[1005];

struct Node
{
char name[25], type[25];
int p, q;
bool operator < (Node temp) const
{
return strcmp(name, temp.name) < 0;
}
}e[1005];

struct Point
{
int no, x;
bool operator < (Point temp) const
{
return x < temp.x;
}
bool operator == (Point temp) const
{
return x == temp.x;
}
}p[1005];

int N, M;

bool Ac(int x)
{
int left = M, idx = -1;
for (int i = 0; i <= 1000; ++i) {
fee[i] = 1 << 30;
}
for (int i = 0; i < N; ++i) {
if (i == 0) {
++idx;
if (mp[e[i].q] >= x) {
fee[idx] = min(fee[idx], e[i].p);
}
}
else {
if (strcmp(e[i].name, e[i-1].name) == 0) {
if (mp[e[i].q] >= x) {
fee[idx] = min(fee[idx], e[i].p);
}
}
else {
left -= fee[idx];
if (left < 0) {
return false;
}
++idx;
if (mp[e[i].q] >= x) {
fee[idx] = min(fee[idx], e[i].p);
}
}
}
}
left -= fee[idx];
if (left < 0) {
return false;
}
return true;
}

int bsearch(int l, int r)
{
int mid, ret = 0;
while (l <= r) {
mid = (l + r) >> 1;
if (Ac(mid)) {
ret = mid;
l = mid + 1;
}
else {
r = mid - 1;
}
}
return ret;
}

int main()
{
int cnt, ret;
int T;
scanf("%d", &T);
while (T--) {
scanf("%d %d", &N, &M);
mp.clear();
for (int i = 0; i < N; ++i) {
scanf("%s %s %d %d", e[i].name, e[i].type, &e[i].p, &e[i].q);
p[i].x = e[i].q;
}
sort(e, e + N);
sort(p, p + N);
cnt = unique(p, p + N) - p;
for (int i = 0; i < cnt; ++i) {
mp[p[i].x] = i;
}
ret = bsearch(0, cnt-1);
printf("%d\n", p[ bsearch(0, cnt-1) ].x);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: