先取正的和负的绝对值较小者为开头 。然后交替从正负数中取绝对值最小但比上一个大的。
证明:
1.开头选正负数中绝对值较小的:否则能再多放1个。
2.交替选的时候选最小的符合条件的:如果大的符合,换小的仍符合。
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <iomanip> #include <cstring> #include <map> #include <queue> #include <set> #include <cassert> #include <stack> #include <bitset> #define mkp make_pair using namespace std; const double EPS=1e-8; typedef long long lon; const lon SZ=800020,INF=0x7FFFFFFF,mod=1000000007; int n,res; struct nd{int val;nd(int a):val(a){}bool operator<(const nd &rbs)const{return abs(val)>abs(rbs.val);} };priority_queue<nd> pos,neg;void init() {for(;pos.size();pos.pop());for(;neg.size();neg.pop());cin>>n;for(int i=0;i<n;++i){int tmp;cin>>tmp;if(tmp<0){neg.push(tmp);}else pos.push(tmp);} }void work() {res=1;if(pos.size()==0||neg.size()==0)return;int pre;bool prekind=0;int a=neg.top().val,b=pos.top().val;if(abs(a)<abs(b)){prekind=0;pre=abs(a);neg.pop();}else{prekind=1;pre=abs(b);pos.pop();}for(;;){if(prekind==0){for(;pos.size()!=0;){if(abs(pos.top().val)<pre)pos.pop();else break;}if(pos.size()==0)break;else{++res;prekind=1;pre=abs(pos.top().val);pos.pop();}}else{for(;neg.size()!=0;){if(abs(neg.top().val)<pre)neg.pop();else break;}if(neg.size()==0)break;else{++res;prekind=0;pre=abs(neg.top().val);neg.pop();}}} }int main() {std::ios::sync_with_stdio(0);//freopen("d:\\1.txt","r",stdin); lon casenum;cin>>casenum;//cout<<casenum<<endl;for(lon time=1;time<=casenum;++time){init();work();cout<<res<<endl;}return 0; }