LA 3971 (二分) Assemble

题意:

你有b块钱想要组装一台电脑。给出n个配件的种类,品质和价格,要求每个种类的配件各买一个总价格不超过b且“品质最差配件”的品质因子应尽量大。

这种情况下STL的map的确很好用,学习学习

 

这种最大值最小的问题可以用二分法,自己写的二分会死循环,学习一下别人的二分。

 

 1 //#define LOCAL

 2 #include <vector>

 3 #include <cstdio>

 4 #include <string>

 5 #include <map>

 6 using namespace std;

 7 

 8 int cnt;    //组件的类型数

 9 map<string, int> id;    //将组件类型的名字与编号对应起来

10 int ID(string s)    //求类型s的编号

11 {

12     if(!id.count(s))    id[s] = cnt++;

13     return id[s];

14 }

15 const int maxn = 1000 + 5;

16 struct Component

17 {

18     int price;

19     int quality;

20 };

21 int n, b;

22 vector<Component> comp[maxn];

23 

24 bool ok(int q)

25 {//品质不小于q的组件能否组成不超过b元的电脑

26     int sum = 0;

27     for(int i = 0; i < cnt; ++i)

28     {

29         int cheapest = b + 1, m = comp[i].size();

30         for(int j = 0; j < m; ++j)

31             if(comp[i][j].quality >= q)

32                 cheapest = min(cheapest, comp[i][j].price);

33                 //选择品质因子不小于p的最便宜的配件

34         if(cheapest > b)    return false;

35         sum += cheapest;

36         if(sum > b)    return false;

37     }

38     return true;

39 }

40 

41 int main(void)

42 {

43     #ifdef LOCAL

44         freopen("3971in.txt", "r", stdin);

45     #endif

46 

47     int T;

48     scanf("%d", &T);

49     while(T--)

50     {

51         scanf("%d%d", &n, &b);

52         cnt = 0;

53         for(int i = 0; i < n; ++i)    comp[i].clear();

54         id.clear();

55 

56         int maxq = 0;

57         for(int i = 0; i < n; ++i)

58         {

59             char type[30], name[30];

60             int p, q;

61             scanf("%s%s%d%d", type, name, &p, &q);

62             maxq = max(maxq, q);

63             comp[ID(type)].push_back((Component) {p, q});

64         }

65 

66         int L = 0, R = maxq;

67         while(L < R)

68         {

69             int M = L + (R - L + 1) / 2;

70             if(ok(M))

71                 L = M;

72             else

73                 R = M - 1;

74         }

75         printf("%d\n", L);

76     }

77     return 0;

78 }
代码君

 

你可能感兴趣的:(sem)