Codeforces Round #413 C. Fountains(优先队列乱搞/树状数组/线段树)
来源:互联网 发布:今日头条视频推荐算法 编辑:程序博客网 时间:2024/05/17 22:24
题目链接:http://codeforces.com/contest/799/problem/C点击打开链接
题意:有金币和钻石 买两个喷泉 要求买最大
一开始用很复杂的思路写了好久 大致就是利用优先队列排序 创立另一个结构体记录每个数量下的金币和钻石能够获得的最大价值 然后遍历每个喷泉与最大金币减去当前喷泉的价值 取最大 注意可能出现重复取的情况 还需判断 比较繁琐
之后学习树状数组 简便许多
#include <stdio.h>#include <stdlib.h>#include <iostream>#include<algorithm>#include <math.h>#include <string.h>#include <limits.h>#include <string>#include <queue>#include <stack>using namespace std;struct xjy{ int val; int cost; char c; bool operator < (const xjy &r) const{ if(cost==r.cost) return val>r.val; return cost>r.cost; }}xjyc[100001],xjyd[100001];struct va{ int val1; int val2; int valcost;}vac[100001],vad[100001];priority_queue<xjy> qc,qd,qcc,qdd;int main(){ int n,coins,dia; scanf("%d%d%d",&n,&coins,&dia); for(int i=0;i<n;i++) { struct xjy mid; scanf("%d%d %c",&mid.val,&mid.cost,&mid.c); if(mid.c=='C') { if(mid.cost<=coins) { qc.push(mid); qcc.push(mid); } } else if(mid.c=='D') { if(mid.cost<=dia) { qd.push(mid); qdd.push(mid); } } } int cmax1=0,cmax2=0,dmax1=0,dmax2=0,ccost=0,dcost=0; for(int i=0;i<=coins;i++) { if(!qc.empty()) { while(i==qc.top().cost&&!qc.empty()) { if(cmax1<=qc.top().val) { cmax2=cmax1; cmax1=max(cmax1,qc.top().val); ccost=qc.top().cost; } qc.pop(); } vac[i].val1=cmax1; vac[i].val2=cmax2; vac[i].valcost=ccost; } else { vac[i].val1=cmax1; vac[i].val2=cmax2; vac[i].valcost=ccost; } } for(int i=0;i<=dia;i++) { if(!qd.empty()) { while(i==qd.top().cost&&!qd.empty()) { if(dmax1<=qd.top().val) { dmax2=dmax1; dmax1=max(dmax1,qd.top().val); dcost=qd.top().cost; } qd.pop(); } vad[i].val1=dmax1; vad[i].val2=dmax2; vad[i].valcost=dcost; } else { vad[i].val1=dmax1; vad[i].val2=dmax2; vad[i].valcost=dcost; } } int sum1=0; while(!qcc.empty()) { xjy mid=qcc.top(); qcc.pop(); if(mid.val==vac[coins-mid.cost].val1&&mid.cost==vac[coins-mid.cost].valcost) { int summid=mid.val+vac[coins-mid.cost].val2; if(vac[coins-mid.cost].val2==0) summid=0; sum1=max(sum1,summid); } else { int summid=mid.val+vac[coins-mid.cost].val1; sum1=max(sum1,summid); } } int sum2=0; while(!qdd.empty()) { xjy mid=qdd.top(); qdd.pop(); if(mid.val==vad[dia-mid.cost].val1&&mid.cost==vad[dia-mid.cost].valcost) { int summid=mid.val+vad[dia-mid.cost].val2; if(vad[dia-mid.cost].val2==0) summid=0; sum2=max(sum2,summid); } else { int summid=mid.val+vad[dia-mid.cost].val1; if(vad[dia-mid.cost].val2==0) summid=0; sum2=max(sum2,summid); } } int sum3=vac[coins].val1+vad[dia].val1; if(vac[coins].val1==0||vad[dia].val1==0) sum3=0; int sum=max(sum1,sum2); sum=max(sum,sum3); printf("%d\n",sum);}
#include <stdio.h>#include <stdlib.h>#include <iostream>#include<algorithm>#include <math.h>#include <string.h>#include <limits.h>#include <string>#include <queue>#include <stack>using namespace std;int coins[111111],dia[111111];int maxn(int *tree,int k){ int maxn=0; while(k>0) { maxn=max(maxn,tree[k]); k-=k&-k; } return maxn;}void add(int *tree,int k,int num){ while(k<=100000) { tree[k]=max(tree[k],num); k+=k&-k; }}int main(){ int n,c,d;int mmax=0;int ans=0;; scanf("%d%d%d",&n,&c,&d); for(int i=0;i<n;i++) { int val,cost;char cchar; scanf("%d%d %c",&val,&cost,&cchar); if(cchar=='C') { mmax=maxn(dia,d); if(cost>c) continue; mmax=max(mmax,maxn(coins,c-cost)); add(coins,cost,val); } else { mmax=maxn(coins,c); if(cost>d) continue; mmax=max(mmax,maxn(dia,d-cost)); add(dia,cost,val); } if(mmax) ans=max(ans,mmax+val); } printf("%d",ans);}
这次线段树写了一遍 更新下吧
线段树与树状数组类似 先查询后更新 这样保证了不会重复取同一个物品 也不会漏掉情况(因为每对物品会有两次取到的情况)
#include <bits/stdc++.h>using namespace std;#define maxn 100010struct xjy{ int left ; int right; int sum;};xjy tree[maxn<<2];struct node{ int val; int cost; bool operator < (const node &r)const { return cost<r.cost; }};vector<node> c,d;void build(int i,int left,int right){ if(left==right) { tree[i].left=left; tree[i].right=right; tree[i].sum=-1; return; } int mid=(left+right)>>1; build (i<<1,left,mid); build(i<<1|1,mid+1,right); tree[i].left=left; tree[i].right=right; tree[i].sum=-1;}void update(int i,int pos,int val){ if(tree[i].left==pos&&tree[i].right==pos) { tree[i].sum=max(tree[i].sum,val);//这里可能有相同价格的 因此是比较而不是等于 return ; } int mid=(tree[i].left+tree[i].right)>>1; if(pos<=mid) update(i<<1,pos,val); else update(i<<1|1,pos,val); tree[i].sum=max(tree[i<<1].sum,tree[i<<1|1].sum);}int aans=0;void query(int i,int left,int right){ if(tree[i].left==left&&tree[i].right==right) { aans=max(aans,tree[i].sum); return ; } int mid =(tree[i].left+tree[i].right)>>1; if(right<=mid) query(i<<1,left,right); else if(left>mid) query(i<<1|1,left,right); else { query(i<<1,left,mid); query(i<<1|1,mid+1,right); }}int main(){ int n,coins,dia; int ans=-1; int cans=-1,dans=-1; scanf("%d%d%d",&n,&coins,&dia); for(int i=1;i<=n;i++) { int val,cost;char cc; scanf("%d%d %c",&val,&cost,&cc); if(cc=='C') { node mid; mid.val=val; mid.cost=cost; c.push_back(mid); if(coins>=cost) cans=max(cans,val); } else { node mid; mid.val=val; mid.cost=cost; d.push_back(mid); if(dia>=cost) dans=max(dans,val); } } if(cans!=-1&&dans!=-1) ans=cans+dans; build(1,1,coins); for(int i=0;i<c.size();i++) { if(coins>c[i].cost) { aans=-1; query(1,1,coins-c[i].cost); if(aans>0) ans=max(ans,c[i].val+aans); update(1,c[i].cost,c[i].val); } } build(1,1,dia); for(int i=0;i<d.size();i++) { if(dia>d[i].cost) { aans=-1; query(1,1,dia-d[i].cost); if(aans>0) ans=max(ans,d[i].val+aans); update(1,d[i].cost,d[i].val); } } if(ans==-1) printf("0"); else printf("%d",ans);}
阅读全文
1 0
- Codeforces Round #413 C. Fountains(优先队列乱搞/树状数组/线段树)
- Codeforces Round #413 C-Fountains 树状数组
- Codeforces Round #413 C. Fountains(RMQ线段树)
- Playrix Codescapes Cup (Codeforces Round #413, rated, Div. 1 + Div. 2) C. Fountains(树状数组)
- Codeforces Round #413:C. Fountains
- Codeforces Round #413 C. Fountains
- codeforces round #413 C. Fountains
- Playrix Codescapes Cup (Codeforces Round #413, rated, Div. 1 + Div. 2) C Fountains 乱搞
- Codeforces Round #225 (Div. 1) C 树状数组 || 线段树
- Codeforces Round #413 Div. 2 C. Fountains
- Codeforces Round #413 C. Fountains 二分
- codeforces 799C Fountains 线段树
- Codeforces Round #225 (Div. 1) C-Propagating tree (DFS序+线段树/树状数组)
- Codeforces Round #413 Div. 1 + Div. 2 C. Fountains
- codeforces Round #413 Div. 1 + Div. 2 C Fountains
- Codeforces 799C Fountains【思维+分类讨论+线段树】
- Codeforces Round 232 Div 1 C On Changing Tree 树状数组 或 线段树
- Codeforces Round #407 (Div. 1) E. New task(线段树+树状数组)
- BZOJ 1176 [Balkan2007]Mokia [CDQ分治+树状数组]
- 小练习2
- python作业
- MFC获取文件夹路径并得到该字符串
- JZ2440的MMU内存管理单元
- Codeforces Round #413 C. Fountains(优先队列乱搞/树状数组/线段树)
- Android应用从后台切换到前台因为数据被GC报异常
- struts2环境搭建步骤
- 函数
- 欧拉角
- js php上传
- 在android studio中生成jar
- linux下使用mysql数据库出现 “Access denied for user 'root'@'localhost' (using password: YES)”
- 《快学Scala》第17章习题参考解答(类型参数)