您的位置:首页 > 其它

uvalive 3971 - Assemble(二分搜索 + 贪心)

2013-08-31 17:47 591 查看
题目连接:3971 - Assemble

题目大意:有若干个零件, 每个零件给出的信息有种类, 名称, 价格, 质量,  现在给出一个金额, 要求在这个金额范围内, 将每个种类零件都买一个, 并且尽量让这些零件中质量最小的越大, 输出质量最小的值。

解题思路:首先可以用二分搜索确定质量, 然后在搜索的过程中要判断这个质量是否能被满足, 判断函数可以用贪心, 在每一类的零件中选择价格最低且质量大于等于当前质量的零件。(事先按照价格大小排序)。

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int N = 1005;
const int M = 25;

struct State {
char name[M];
int money;
int wei;
}s

;
int cnt, sum, son
;
char str
[M], sex[M];

bool cmp(const State& a, const State& b) {
return a.money < b.money;
}

int find(char sex[]) {
for (int i = 0; i < cnt; i++)
if(strcmp(sex, str[i]) == 0)
return i;
strcpy(str[cnt], sex);
return cnt;
}

bool judge(int Min) {
int tmp = 0;
for (int i = 0; i < cnt; i++) {
int flag = 1;
for (int j = 0; j < son[i]; j++) {
if (s[i][j].wei >= Min) {
flag = 0;
tmp += s[i][j].money;
break;
}
}
if (flag || tmp > sum)	return false;
}
return true;
}

int main() {
State now;
int cas, n, cur, L, R;
scanf("%d", &cas);
while (cas--) {
memset(s, 0, sizeof(s));
memset(son, 0, sizeof(son));
memset(str, 0, sizeof(str));
cnt = L = R = 0;

scanf("%d%d", &n, &sum);
for (int i = 0; i < n; i++) {
scanf("%s%s%d%d", sex, now.name, &now.money, &now.wei);
if (now.wei > R)	R = now.wei;
cur = find(sex);
s[cur][son[cur]++] = now;
if (cur == cnt) cnt++;
}

for (int i = 0; i < cnt; i++)
sort(s[i], s[i] + son[i], cmp);

int mid;
while (L < R) {
mid = (L + R) / 2;
if (L == mid)   break;
if (judge(mid))
L = mid;
else
R = mid;
}
if (judge(mid + 1)) mid++;
printf("%d\n", mid);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: