刷怪升级
2017-08-23 18:33
19 查看
【问题描述】
小 A 小 B 小 C 要共同协作刷掉 n 个怪物才可通关升级,其中第 i 个怪物拥有 a[i]的物理防御力,b[i]的魔法防御力,c[i]的精神防御力。如果想要打死第 i 只怪物,需要自身的物理攻击力不小于 a[i]或者魔法攻击力不小于 b[i]或者精神攻击力不小于 c[i]。
他们经过简单的计算发现其实每个人只要专注于提升三种攻击力中的一种即可,因为这一定更划算。无论提升哪种攻击力,每提升 1 个单位攻击需要花费 1 个单位的钱。起初他们的所有攻击力均为 0,问他们最小需要多少单位的钱即可刷掉 n 个怪物。
【输入】
第一行一个数 n,表示 n 个怪物。
接下来 n 行,每行三个数 ai, bi, ci 表示一只怪物的物理防御力,魔法防御力和精神防
御力。
【输出】
一行一个数,表示需要最少花费多少单位的钱。
【输入输出样例】
Input
3
2 2 100
1 100 3
100 4 5
Output
5
【样例解释】
A = {(1, 100, 3)}
B = {(100, 4, 5),(2, 2, 100)}
C = {}
小 A 负责打第二个怪物,小 A 只需提升 1 点物理攻击即可打败。
小 B 负责打第一个和第三个怪物,需要提升 4 点魔法攻击。
小 C 负责加油助♂威。
共需花费 1+4=5 个单位的钱。
【数据范围与约定】
存在 30%的数据,1 <= n <= 300, 1 <= ai, bi, ci <= 300
存在 40%的数据,1 <= n <= 100000, 1 <= ai,bi <= 100000, ci 均为 100000000
存在 20%的数据,1 <= n <= 100000, 1 <= ai, bi, ci <= 100000
存在 10%的数据,1 <= n <= 100000, 1 <= ai, bi, ci <= 100000000
上述数据覆盖约束覆盖了 100%的测试数据。
【题解】
这道题好像有几种方法:
方法一:暴力乱搞
复杂度指数级别,竟然过了,还跑的比其他方法都快orzorzorzorzorz…..
(完美诠释“骗分过样例,暴力出奇迹”)
方法二:线段树(什么鬼思想搞不懂,看来我听学长讲课时要做笔记了)
方法三:set(还是搞不懂QAQ)
小 A 小 B 小 C 要共同协作刷掉 n 个怪物才可通关升级,其中第 i 个怪物拥有 a[i]的物理防御力,b[i]的魔法防御力,c[i]的精神防御力。如果想要打死第 i 只怪物,需要自身的物理攻击力不小于 a[i]或者魔法攻击力不小于 b[i]或者精神攻击力不小于 c[i]。
他们经过简单的计算发现其实每个人只要专注于提升三种攻击力中的一种即可,因为这一定更划算。无论提升哪种攻击力,每提升 1 个单位攻击需要花费 1 个单位的钱。起初他们的所有攻击力均为 0,问他们最小需要多少单位的钱即可刷掉 n 个怪物。
【输入】
第一行一个数 n,表示 n 个怪物。
接下来 n 行,每行三个数 ai, bi, ci 表示一只怪物的物理防御力,魔法防御力和精神防
御力。
【输出】
一行一个数,表示需要最少花费多少单位的钱。
【输入输出样例】
Input
3
2 2 100
1 100 3
100 4 5
Output
5
【样例解释】
A = {(1, 100, 3)}
B = {(100, 4, 5),(2, 2, 100)}
C = {}
小 A 负责打第二个怪物,小 A 只需提升 1 点物理攻击即可打败。
小 B 负责打第一个和第三个怪物,需要提升 4 点魔法攻击。
小 C 负责加油助♂威。
共需花费 1+4=5 个单位的钱。
【数据范围与约定】
存在 30%的数据,1 <= n <= 300, 1 <= ai, bi, ci <= 300
存在 40%的数据,1 <= n <= 100000, 1 <= ai,bi <= 100000, ci 均为 100000000
存在 20%的数据,1 <= n <= 100000, 1 <= ai, bi, ci <= 100000
存在 10%的数据,1 <= n <= 100000, 1 <= ai, bi, ci <= 100000000
上述数据覆盖约束覆盖了 100%的测试数据。
【题解】
这道题好像有几种方法:
方法一:暴力乱搞
复杂度指数级别,竟然过了,还跑的比其他方法都快orzorzorzorzorz…..
(完美诠释“骗分过样例,暴力出奇迹”)
#include<cstdio> #include<iostream> #include<cstring> using namespace std; int n; int a[100001],b[100001],c[100001]; int ans=1<<30; void dfs(int u,int x,int y,int z) { if(x+y+z>=ans)return; if(u==n+1) { ans=min(ans,x+y+z); return; } if(a[u]<=x||b[u]<=y||c[u]<=z) { dfs(u+1,x,y,z); return; } dfs(u+1,a[u],y,z); dfs(u+1,x,b[u],z); dfs(u+1,x,y,c[u]); } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d%d%d",&a[i],&b[i],&c[i]); dfs(1,0,0,0); printf("%d",ans); fclose(stdin); fclose(stdout); }
方法二:线段树(什么鬼思想搞不懂,看来我听学长讲课时要做笔记了)
#include<cstdio> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> using namespace std; const int MAX=150005; int n,m,B,C,b[MAX],o[MAX],ans=2147483647; struct segtree { int mn,mc; int lazy; }t[MAX<<2]; struct node{int a,b,c;}w[MAX]; int gi() { int x=0,w=1;char ch=getchar(); while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar(); if (ch=='-') w=-1,ch=getchar(); while (ch>='0'&&ch<='9') { x=x*10+ch-'0'; ch=getchar(); } return x*w; } bool cmp(node x,node y) {return x.a<y.a;} void Pushdown(int now,int l,int r) { if (!t[now].lazy) return; int mid=l+r>>1; t[now<<1].mn=b[l]+t[now].lazy; t[now<<1|1].mn=b[mid+1]+t[now].lazy; t[now<<1].mc=t[now].lazy;t[now<<1].lazy=t[now].lazy; t[now<<1|1].mc=t[now].lazy;t[now<<1|1].lazy=t[now].lazy; t[now].lazy=0; } void Update(int now) { t[now].mn=min(t[now<<1].mn,t[now<<1|1].mn); t[now].mc=min(t[now<<1].mc,t[now<<1|1].mc); } void Build(int now,int l,int r) { if (l==r) { t[now].mn=b[l]; return; } int mid=l+r>>1; Build(now<<1,l,mid); Build(now<<1|1,mid+1,r); Update(now); } int Query(int now,int l,int r,int ql,int qr,int val) { Pushdown(now,l,r); if (t[now].mc>=val) return 0; if (l==r) return l; int mid=l+r>>1,res=0; if (ql<=mid) res=Query(now<<1,l,mid,ql,qr,val); if (qr>mid&&!res) res=Query(now<<1|1,mid+1,r,ql,qr,val); Update(now); return res; } void Modify(int now,int l,int r,int ql,int qr,int val) { Pushdown(now,l,r); if (l>=ql&&r<=qr) { t[now].mn=b[l]+val;t[now].mc=val;t[now].lazy=val; return; } int mid=l+r>>1; if (ql<=mid) Modify(now<<1,l,mid,ql,qr,val); if (qr>mid) Modify(now<<1|1,mid+1,r,ql,qr,val); Update(now); } int main() { //freopen("playwithboss.in","r",stdin); //freopen("playwithboss.out","w",stdout); n=gi(); for (int i=1;i<=n;i++) w[i]=(node){gi(),gi(),gi()}; for (int i=1;i<=n;i++) b[i]=w[i].b; sort(b+1,b+n+1); m=unique(b+1,b+n+1)-b-1; //for (int i=1;i<=m;i++) b[i]=o[i]; for (int i=1;i<=n;i++) w[i].b=lower_bound(b+1,b+m+1,w[i].b)-b; Build(1,1,m); sort(w+1,w+n+1,cmp); for (int i=n;i>0;i--) { Pushdown(1,1,m); ans=min(ans,w[i].a+t[1].mn); ans=min(ans,C+w[i].a),C=max(C,w[i].c); ans=min(ans,B+w[i].a),B=max(B,b[w[i].b]); if (w[i].b>1) { int t=Query(1,1,m,1,w[i].b-1,w[i].c); if (t) Modify(1,1,m,t,w[i].b-1,w[i].c); } } Pushdown(1,1,m); ans=min(ans,t[1].mn); ans=min(ans,C); ans=min(ans,B); //for (int i=1;i<=20;i++) // printf("now=%d mn=%d mc=%d lazy=%d\n",i,t[i].mn,t[i].mc,t[i].lazy); printf("%d",ans); return 0; }
方法三:set(还是搞不懂QAQ)
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> #include <queue> #include <set> using namespace std; typedef pair<int,int> pir; const int N=100010,Inf=1<<30; int n; int a ,b ,c ,id ; set <pir> w; inline int gi() { int x=0,o=1; char ch=getchar(); while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar(); if(ch=='-') ch=getchar(),o=-1; while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x*o; } struct Que { priority_queue <int,vector<int>,greater<int> > p,q; inline void push(int x) {p.push(x);} inline void delet(int x) {q.push(x);} inline int top() { while(!q.empty()&&p.top()==q.top()) p.pop(),q.pop(); return p.top(); } } Q; inline bool cmp(const int &x,const int &y) { return a[x]>a[y]; } inline void insert(int x) { set <pir> :: iterator t=w.lower_bound(pir(b[x],c[x])),p; if(t->second>=c[x]) return; if(t->first>b[x]) --t; while(1) { if(t->second>c[x]) { Q.delet(t->first+(++t)->second); t=w.insert(pir(b[x],c[x])).first; Q.push(c[x]+(--t)->first); ++t,Q.push(b[x]+(++t)->second); return; } Q.delet(t->second+(p=--t)->first); ++t,Q.delet(t->first+(++t)->second); Q.push(p->first+t->second); w.erase(--t),t=p; } } int main() { int ans=Inf ; cin>>n; for(int i=1;i<=n;i++) a[i]=gi(),b[i]=gi(),c[i]=gi(),id[i]=i; sort(id+1,id+1+n,cmp); Q.push(0); w.insert(pir(0,Inf)),w.insert(pir(Inf,0)); for(int i=1;i<=n;i++) { ans=min(ans,a[id[i]]+Q.top()); insert(id[i]); } cout<<min(ans,Q.top()); return 0; }
相关文章推荐
- 【杭二联考】刷怪升级
- 如何升级更新到CleanMyMac 3
- C#Winform程序的打包,发布和升级
- uniGUI0.93项目升级到0.94版报a.on is not a function 的解决办法
- android sqlite 数据库升级
- live spaces 功能升级
- 程序员升级必备
- websphere7.0下载升级程序和补丁及安装
- Win10 Mobile手机版、PC应用商店升级:详细列出内购项目及价格清单
- APP版本升级,数据库数据如何办?
- 升级到XP系统以后网速变慢但驱动程序都安装正常
- centos 6.4x64 django开发环境搭建(升级python2.6.6为2.7.3)
- 忙里偷闲将 VelocityWeb 升级到 0.95 版本
- 基线升级---merge方法分析
- 升级docker至最新版本
- Exchange2003升级到2010的注意事项 推荐
- RedHat升级内核成功
- Xcode - 升级后模拟器无法响应电脑键盘
- Unity5.x 项目升级过程中常见问题解决方案总结
- 一篇关于从B2TR升级到RTM的好文章