题目链接:https://codeforces.com/problemset/problem/799/C
题意:有 c 块硬币和 d 块钻石,每种喷泉消耗硬币或钻石中的一种,每个喷泉有一个美丽值,问建造两个喷泉可以获得的最大美丽值是多少。
题解:三种情况:买两个消耗硬币的喷泉,买两个消耗钻石的喷泉或各买一个,消耗的范围是1e5,故用树状数组维护之前的最大值,考虑加入当前建造的更新答案。
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define ull unsigned long long 5 #define mst(a,b) memset((a),(b),sizeof(a)) 6 #define mp(a,b) make_pair(a,b) 7 #define pi acos(-1) 8 #define pii pair<int,int> 9 #define pb push_back 10 #define lowbit(x) ((x)&(-x)) 11 const int INF = 0x3f3f3f3f; 12 const double eps = 1e-6; 13 const int maxn = 1e5 + 10; 14 const int maxm = 1e6 + 10; 15 const ll mod = 998244353; 16 17 void add(int a[],int pos,int val) { 18 while(pos < maxn) { 19 a[pos] = max(a[pos],val); 20 pos += lowbit(pos); 21 } 22 } 23 24 int query(int a[],int pos) { 25 int ans = 0; 26 while(pos) { 27 ans = max(ans,a[pos]); 28 pos -= lowbit(pos); 29 } 30 return ans; 31 } 32 33 int a[maxn],b[maxn]; 34 35 int main() { 36 #ifdef local 37 freopen("data.txt", "r", stdin); 38 // freopen("data.txt", "w", stdout); 39 #endif 40 int n,c,d; 41 scanf("%d%d%d",&n,&c,&d); 42 int ans = 0; 43 for(int i = 0; i < n; i++) { 44 int bea,cost; 45 char s[10]; 46 scanf("%d%d%s",&bea,&cost,s); 47 int mx = 0; 48 if(s[0] == 'C') { 49 if(cost > c) continue; 50 int can = query(b,d); 51 if(can) mx = bea + query(b,d); 52 can = query(a,c - cost); 53 if(can) mx = max(mx, bea + can); 54 add(a,cost,bea); 55 } else { 56 if(cost > d) continue; 57 int can = query(a,c); 58 if(can) mx = bea + query(a,c); 59 can = query(b,d - cost); 60 if(can) mx = max(mx, bea + can); 61 add(b,cost,bea); 62 } 63 ans = max(ans, mx); 64 } 65 printf("%d ",ans); 66 return 0; 67 }