UVALive 3971 Assemble(模拟 + 二分)

UVALive 3971

题意:有b块钱,想要组装一台电脑,给出n个配件的种类,名字,价格,品质因子。若各种类配件各买一个,总价格<=b,求最差品质配件的最大品质因子。

思路:

求最大的最小值一般用二分法。

在(0,maxq)内进行二分,判定q作为最差品质因子是否可行。

大白书原题,比较考验代码功底。

code:

/*
* @author Novicer
* language : C++/C
*/
#include<iostream>
#include<sstream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<ctime>
#include<iomanip>
using namespace std;
const double eps(1e-8);
typedef long long lint;

const int  maxn = 1000 + 5;

map<string,int> id;
int n,b;
int cnt = 0;

struct Comp{
	int price;
	int quality;
};

vector<Comp> comp[maxn];

int ID(string s){
	if(!id.count(s)){
		id[s] = cnt++;
	}
	return id[s];
}

bool ok(int q){
	int sum = 0;
//	cout << q << endl;
	for(int i = 0 ; i < cnt ; i++){
		int cheapest = b + 1;
		for(int j = 0 ; j < comp[i].size() ; j++){
//			cout << comp[i][j].price << endl;
			if(q <= comp[i][j].quality) cheapest = min(cheapest , comp[i][j].price);
		}
		if(cheapest == b+1) return false;
		sum += cheapest;
//		cout << "q : " << q << " sum : " << sum << endl;
		if(sum > b) return false;
	}
	return true;
}
int solve(int l , int r){
	while(l <  r){
		int m = l + (r - l + 1)/2;
		if(ok(m)) l = m;
		else r = m - 1;
//		cout << m << endl;
	}
	return l;
}
int main(){
//	freopen("input.txt","r",stdin);
	int T;
	cin >> T;
	while(T--){
		cnt = 0;
		cin >> n >> b;
		for(int i = 0 ; i < n ; i++) comp[i].clear();
		int maxq = 0;
		for(int i = 1 ; i <= n ; i++){
			string type,name;
			int p,q;
			cin >> type >> name >> p >> q;
//			cout << type << name << p << q << endl;
			maxq = max(maxq , q);
			Comp tmp;
			tmp.price = p; tmp.quality = q;
			comp[ID(type)].push_back(tmp);
		}
//		cout << maxq << endl;
		int L = 0 , R = maxq;
		int ans = solve(L,R);
		cout << ans << endl;
	}
	return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-10 07:37:09

UVALive 3971 Assemble(模拟 + 二分)的相关文章

UVALive 3971 Assemble(二分+贪心)

本题思路不难,但是要快速准确的AC有点儿考验代码功力. 看了大白书上的标程,大有所获. 用map和vector的结合给输入分组,这个数据结构的使用非常精美,恰到好处. #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<cmath> #include<map> #include&l

UVA 12124 UVAlive 3971 Assemble(二分 + 贪心)

先从中找出性能最好的那个数, 在用钱比较少的去组合,能组出来就表明答案在mid的右边,反之在左边, #include<string.h> #include<map> #include<stdio.h> #include<iostream> #include<algorithm> using namespace std; map<string,int> vic;//以字符映射数字 int end,start; int num; int

[2016-03-19][UVALive][3971][Assemble]

时间:2016-03-19 13:55:17 星期六 题目编号:[2016-03-19][UVALive][3971][Assemble] 题目大意:给定若干个电脑零件的价格和质量,求在总价不超过b的情况下,品质最差的配件的质量尽可能大 分析:二分 #include <vector> #include <map> #include <algorithm> #include <string> #include <cstring> #include

uvalive 3971 Assemble

https://vjudge.net/problem/UVALive-3971 题意: 现在你要组装一台电脑,每个电脑的一种类型的配件都有多种选择,它们的名字是不同的. 现在给出已有的元件,每种类型都至少有一个元件.你有已知的预算,要求你找出以不超过预算的钱,每种类型的元件恰好选择一个,最低质量的元件的质量要尽量高,输出这个最高值. 思路: 从题意的叙述来看,最大化最小值,那么肯定是选用二分. 二分选择的量应该是质量. 接下来证明花费的钱是随着质量非递减的. 设当前的最小质量为x,那么把所有元件

codevs 1083 1083 Cantor表【模拟+二分改进】

题目链接: http://codevs.cn/problem/1083/ 一个模拟题,列表出来就是酱紫: 这样为了找到数据在哪一组,很明显就要二分一下,自己写一个改进的二分,类似STL中的lower_bound... 1 #pragma comment(linker, "/STACK:16777216") //防爆栈 2 #include<iostream> 3 #include<algorithm> 4 #include<cstdio> 5 #in

UVALive 6168 Fat Ninjas --二分小数+搜索

题意:一个NxN的网格地板,有一些激光束从天花板垂直射向地面的某个网格,一个圆要安全地从左走到右,不碰到上边界,下边界以及激光束,问这个圆的直径最大能达到多大. 分析:可以二分直径,关键在check函数的写法.可以讲这个圆缩成一个点,把圆的直径转化为激光的扫描范围,当激光范围完全堵死一条通道的时候,这个直径则是不可行的.怎样判断是否堵死一条通道了呢.每次check(dis)的时候,枚举激光束对,如果激光束之间距离小于dis,那么它们两个之间建一条边.还要注意处理边界,如果激光束范围与上边界或下边

UVALive 3634 数据结构模拟

这题真是坑啊,题意不明,其实就是往桟里面压入空的set集合,所以之前的询问大小都是只有0,只有add的时候,才会产生新的占空间的集合 用stack和set直接进行模拟 #include <iostream> #include <cstdio> #include <cstring> #include <set> #include <stack> #include <map> using namespace std; int cnt; s

FZU 1575 小学生的游戏【模拟二分】

某天,无聊的小斌叫上几个同学玩游戏,其中有比较笨的小兴,比较傻的小雪,可爱的小霞和自以为是的小楠.他们去找聪明的小明去给他们当裁判.判定谁取得游戏胜利. 而这个游戏是由小斌想个1到10000000的数字让大家猜,看谁先猜中.为了防止小斌作弊,小明记录下了游戏的整个过程.你的任务是判断小斌是否有作弊. Input 输入数据包括多盘游戏.一次猜数包含两行,第一行是一个数字n(1<=n<=10000000),表示所猜数字.第二行是小斌的回答为"too high","to

UVALive - 3211 (2-SAT + 二分)

layout: post title: 训练指南 UVALive - 3211 (2-SAT + 二分) author: "luowentaoaa" catalog: true mathjax: true tags: - 2-SAT - 图论 - 训练指南 Now or later UVALive - 3211 题意 n架飞机,每架可选择两个着落时间.安排一个着陆时间表,使得着陆间隔的最小值最大 题解 二分查找最大值P,每次都用2-SAT判断是否可行. #include<bits