http://codeforces.com/gym/101806/problem/T
In the year 2117, Professor Jaemin Yu developed a linear-time algorithm for TSP(Traveling Salesperson Problem). Not long after that happened, all computer systems were destroyed, and nuclear weapons demolished all the lands. You, a great computer expert, also lost your job. With a great despair, you lost your meaning of life long ago. All those things that made your heart beat – where had they gone? After questioning yourself again and again, your conclusion is ...
"If I go to KAIST where I started my first ICPC, can I find a meaning of my life?"
All transportations were destroyed, but you were an avid ICPC participant, and you collected a lot of century-old balloons in Korean Regionals. If you could float a house with some of those balloons...
Currently you have N balloons, and you are trying to float the house into the sky by attaching balloons on the rooftop. Every balloon have altitude limit Li and capacity Di, which indicates you can blow balloons in altitude at most Li, and the balloon busts after increasing the altitude by Di.
Your journey starts at altitude 0. If you have more than 1 balloons enlarged, then the house will ascend too fast. Thus, you will blow one balloon and attach it at the rooftop, increase the altitude until the balloons bust, blow the other balloon and attach it to increase the altitude... to make your house float. For convenience, you may assume that balloons can only increase the altitude.
You don‘t care about your final altitude, but a balloon can move a fixed amount of distance. Thus, you want to bust as many balloons as possible. You want to calculate a maximum number of balloons you can bust, and check if you can make a journey to KAIST. Let‘s see whether your 100-year-old ICPC experience can help on this problem!
The first line contains N, the number of balloons. (1 ≤ N ≤ 250, 000)
In next N lines, the altitude limit of i-th balloon Li, and capacity of i-th balloon Di are given as two space-separated integers. (0 ≤ Li ≤ 1015, 1 ≤ Di ≤ 109)
Print the maximum number of balloons you can bust.
类似于UVA 1153
但是发现个问题,按照$L_i$从小到大排序后再用堆将当前任务与之前的任务交换的做法会WA
而按照$L_i+D_i$从小到大排序后再用堆将当前任务与之前的任务交换的做法会AC
按照顺序考虑选气球的问题,将考虑第$a_i$个气球(按照某个顺序选某个特定的气球)设为第$i$个阶段,解为选择的气球数,第1个阶段很容易得到最大的解是什么
数学归纳法,假设之前考虑的阶段都已经达到最大的解了,现在考虑这一阶段(这个气球是否选)
因此每一个阶段只需要考虑答案是+1还是维持不变(注意,只考虑了数量没有考虑选什么,选的顺序)
也就是,在之前是最优解的情况下
因此我们必须保证不能增加气球的时候才不增加气球= =(这不是废话吗……)
每一阶段都是考虑的气球的数量,而不是哪一个气球,因此要在丢掉某些气球、选另外一些气球、改变顺序仍然无法增加气球数量时才保持不变
为了简化,我们按照顺序考虑每一个气球
考虑丢掉某些气球,选另外一些气球:
考虑改变顺序
因此问题就变成了确定选气球的顺序
假设是$a+b$和$c+d$
肯定能至少选一个,如果$b\leqslant c$,不交换顺序能完成两个,如果$d\leqslant a$,交换顺序能完成两个
变下形,$b+d\leqslant c+d$,$b+d\leqslant a+b$,得到$c+d$大时不交换,$a+b$大时交换
我太弱智了,写了一大坨结果还是不会,本来是想练手写堆的
AC代码
#include<cstdio> #include<cstdlib> #include<cctype> #include<cstring> #include<algorithm> #include<set> #include<cassert> #define REP(r,x,y) for(register int r=(x); r<(y); r++) #define REPE(r,x,y) for(register int r=(x); r<=(y); r++) #define PERE(r,x,y) for(register int r=(x); r>=(y); r--) #ifdef sahdsg #define DBG(...) printf(__VA_ARGS__),fflush(stdout) #else #define DBG(...) (void)0 #endif using namespace std; typedef long long LL; typedef unsigned long long ULL; char ch; int si; char buf[1<<21],*p1=buf,*p2=buf; int beof = 0; #define gc() (beof?EOF:(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?(beof=EOF):*p1++)) #define gl(x) {char*s=x;while(isspace(*s=gc()));s++;while(!isspace(*s=gc()))s++;*s=0;} template<class T> inline void read(T &x) { x=0; si=1; for(ch=gc();!isdigit(ch) && ch!=‘-‘;ch=gc()) if(beof) return; if(ch==‘-‘){si=-1,ch=gc();} for(;isdigit(ch);ch=gc())x=x*10+ch-‘0‘; x*=si; } //template<class T, class...A> inline void read(T &x, A&...a){read(x); read(a...);} #define MAXN 250007 struct node { LL l, d; } hp[MAXN]; inline bool cmp(const node& l, const node& r) { return l.l<r.l; } namespace _hp { int sz=0; inline void down() { for(int f=2; f<=sz; f<<=1) { if(f<sz && hp[f].d<hp[f+1].d) f++; if(hp[f].d>hp[f>>1].d) { swap(hp[f],hp[f>>1]); } else { break; } } } inline void up() { for(int f=sz; f>1; f>>=1) { if(hp[f].d>hp[f>>1].d) { swap(hp[f],hp[f>>1]); } else { break; } } } inline void hpins(LL l, LL d) { sz++; hp[sz].l=l, hp[sz].d=d; up(); } inline node& hppop() { swap(hp[1],hp[sz]); sz--; down(); return hp[sz+1]; } } using _hp::hpins; using _hp::hppop; node arr[MAXN]; int main() { #ifdef sahdsg freopen("in.txt", "r", stdin); #endif int n; read(n); REP(i,0,n) { read(arr[i].l); read(arr[i].d); arr[i].l+=arr[i].d; } sort(arr,arr+n,cmp); LL now=0, ans=0; REP(i,0,n) { hpins(arr[i].l, arr[i].d); now+=arr[i].d; if(now<=arr[i].l) { ans++; } else { LL d=hppop().d; now-=d; } } printf("%lld\n", ans); return 0; }
原文:https://www.cnblogs.com/sahdsg/p/10859694.html