799C(xjb)

题目链接: http://codeforces.com/problemset/problem/799/C

 

题意: 有c, d两种货币, 有 n 个货物, 可以用 c 货币或者 d 货币购买, 现在需要买两件货物, 问购买的货物的美丽值最大可为多少.

 

思路: 只买两件货物, 那么总共有 3 总可能, 买一件 c 一件 d, 买两件 c 或者买两件 d . 取他们的最大值即可.

可以给 c 货物和 d 货物按 p 升序排列, 那么对于买一件 c 一件 d 的情况, 只需要遍历一下 c 货物 和 d 货物, 分别取能买到的最大 b 值即可.

对于买两件 c 的情况,  用 vis[k] 存储当前 k 个 c 货币最大可买到的 b 值. 那么可以遍历c 货物的同时更新 vis 数组, 即对于当前 i , vis[k] 存储 [0, i) 中 k 可以买到的最大价值.

那么对于每一个 i , 匹配一下 vis[c - gel_c[i].p] 即可, 然后维护一下 gel_c[i].b + vis[c - gel_c[i].p] 的最大值即可.

对于选两件 d 的情况, 和选两个 c 的情况处理方法相同.

 

代码:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <algorithm>
 4 #include <string.h>
 5 using namespace std;
 6 
 7 const int MAXN = 1e5 + 10;
 8 struct node{
 9     int b, p;
10 }gel_c[MAXN], gel_d[MAXN];
11 
12 int vis[MAXN], tag[MAXN];
13 
14 bool cmp(node x, node y){
15     return x.p < y.p;
16 }
17 
18 int main(void){
19     char op[5];
20     int n, c, d, indx_c = 0, indx_d = 0, ans = 0;
21 
22     scanf("%d%d%d", &n, &c, &d);
23     for(int i = 0; i < n; i++){
24         int b, p;
25         scanf("%d%d%s", &b, &p, op);
26         if(op[0] == 'C'){
27             gel_c[indx_c].b = b;
28             gel_c[indx_c++].p = p;
29         }else{
30             gel_d[indx_d].b = b;
31             gel_d[indx_d++].p = p;
32         }
33     }
34 
35     sort(gel_c, gel_c + indx_c, cmp);
36     sort(gel_d, gel_d + indx_d, cmp);
37 
38     int cnt1 = 0, cnt2 = 0, pos = 0;
39     for(int i = 0; i < indx_c; i++){
40         if(gel_c[i].p > c) break;
41         cnt1 = max(cnt1, gel_c[i].b);
42     }
43     for(int i = 0; i < indx_d; i++){
44         if(gel_d[i].p > d) break;
45         cnt2 = max(cnt2, gel_d[i].b);
46     }
47     if(cnt1 && cnt2) ans = cnt1 + cnt2;
48 
49     cnt1 = cnt2 = 0;
50     for(int i = 0; i < indx_c; i++){
51         int gg = c - gel_c[i].p;
52         if(gg <= 0) break;
53         int cc = upper_bound(tag, tag + pos, gg) - tag;
54         if(cc == 0 && i != 0) break;
55         cc = tag[cc - 1];
56         if(vis[cc]) ans = max(ans, gel_c[i].b + vis[cc]);
57         vis[gel_c[i].p] = max(cnt1, gel_c[i].b);
58         tag[pos++] = gel_c[i].p;
59         cnt1 = max(cnt1, gel_c[i].b);
60     }
61 
62     pos = 0;
63     for(int i = 0; i < indx_d; i++){
64         int gg = d - gel_d[i].p;
65         if(gg <= 0) break;
66         int cc = upper_bound(tag, tag + pos, gg) - tag;
67         if(cc == 0 && i != 0) break;
68         cc = tag[cc - 1];
69         if(vis[cc]) ans = max(ans, gel_d[i].b + vis[cc]);
70         vis[gel_d[i].p] = max(cnt2, gel_d[i].b);
71         tag[pos++] = gel_d[i].p;
72         cnt2 = max(cnt2, gel_d[i].b);
73     }
74     printf("%d\n", ans);
75     return 0;
76 }
View Code

 

posted @ 2017-07-08 12:42  geloutingyu  阅读(301)  评论(0编辑  收藏  举报