标签:
题目链接:点击打开链接
题意: 给n个组件来组装电脑, 每个组件有4个属性:种类、名称、价格、品质。 要求每种组件买一个, 求在不超过预算的情况下, 品质最低的品质尽量大。
思路:很显然, 二分最低品质, 然后判断是否可行, 属于二分找上界,在二分时有一个小技巧用来处理当区间相差1时的情况。
细节参见代码:
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<string> #include<vector> #include<stack> #include<bitset> #include<cstdlib> #include<cmath> #include<set> #include<list> #include<deque> #include<map> #include<queue> #define Max(a,b) ((a)>(b)?(a):(b)) #define Min(a,b) ((a)<(b)?(a):(b)) using namespace std; typedef long long ll; typedef long double ld; const ld eps = 1e-9, PI = 3.1415926535897932384626433832795; const int mod = 1000000000 + 7; const int INF = int(1e9); const ll INF64 = ll(1e18); const int maxn = 1000 + 10; int T,n,b,cnt,val,pp; struct node { int val, p; node(int val=0, int p=0):val(val), p(p) {} bool operator < (const node& rhs) const { return val < rhs.val; } }; vector<node> g[maxn]; map<string, int> p; bool ok(int m) { int ans = 0; for(int i=0;i<cnt;i++) { bool flag = false; int len = g[i].size(); for(int j=0;j<len;j++) { node &u = g[i][j]; if(u.p >= m) { ans += u.val; flag = true; break; } } if(!flag) return false; if(ans > b) return false; } return true; } char s[100],name[100]; int main() { scanf("%d",&T); while(T--) { scanf("%d%d",&n,&b); p.clear(); for(int i=0;i<n;i++) g[i].clear(); cnt = 0; int minv = INF, maxv = -INF; for(int i=0;i<n;i++) { scanf("%s%s%d%d",s,name,&val,&pp); minv = min(minv, pp); maxv = max(maxv, pp); if(!p.count(s)) { p[s] = cnt; g[cnt].push_back(node(val, pp)); ++cnt; } else { int id = p[s]; g[id].push_back(node(val, pp)); } } for(int i=0;i<cnt;i++) { sort(g[i].begin(), g[i].end()); } int l = minv, r = maxv, mid; while(r > l) { mid = (l + r + 1) >> 1; if(ok(mid)) l = mid; else r = mid - 1; } printf("%d\n",l); } return 0; }
标签:
原文地址:http://blog.csdn.net/weizhuwyzc000/article/details/50727107