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 }
我就是我,颜色不一样的烟火 --- geloutingyu