[hdu5360]贪心
题意:一个人想邀请n个人出去玩,假设当前同意和他一起去的人数为cnt,那么他去邀请i的时候,i同意的条件是L[i]<=cnt<=R[i],L[i],R[i]是给定的,问怎样安排邀请顺序,使得有最多的人同意
思路:由于同意他的条件是cnt,不妨在当前状态下将所有没被邀请的人分成3类,一种是R[i]<cnt的,一种是L[i]<=cnt<=R[i]的,一种是L[i]>cnt的,对于第一种已经不可能同意了,因为cnt是递增的,对于第三种现在根本不用考虑,而对于第二种,那么都可以被邀请,且被邀请了一定会同意。明显应该邀请R[i]最小的,因为他们总是比其他人最先变成第一种人。于是得到一个贪心算法,每次选择L[i]<=cnt的所有没邀请的人中R[i]最小的。而这可以每次在cnt发生变化时,用set来维护第二种人的集合,并可以在logn的时间内找到R[i]最小的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | #include <map> #include <set> #include <cmath> #include <ctime> #include <deque> #include <queue> #include <stack> #include <vector> #include <cstdio> #include <string> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define X first #define Y second #define pb push_back #define mp make_pair #define all(a) (a).begin(), (a).end() #define fillchar(a, x) memset(a, x, sizeof(a)) typedef long long ll; typedef pair< int , int > pii; typedef unsigned long long ull; #ifndef ONLINE_JUDGE void RI(vector< int >&a, int n){a.resize(n); for ( int i=0;i<n;i++) scanf ( "%d" ,&a[i]);} void RI(){} void RI( int &X){ scanf ( "%d" ,&X);} template < typename ...R> void RI( int &f,R&...r){RI(f);RI(r...);} void RI( int *p, int *q){ int d=p<q?1:-1; while (p!=q){ scanf ( "%d" ,p);p+=d;}} void print(){cout<<endl;} template < typename T> void print( const T t){cout<<t<<endl;} template < typename F, typename ...R> void print( const F f, const R...r){cout<<f<< ", " ;print(r...);} template < typename T> void print(T*p, T*q){ int d=p<q?1:-1; while (p!=q){cout<<*p<< ", " ;p+=d;}cout<<endl;} #endif template < typename T> bool umax(T&a, const T&b){ return b<=a? false :(a=b, true );} template < typename T> bool umin(T&a, const T&b){ return b>=a? false :(a=b, true );} template < typename T> void V2A(T a[], const vector<T>&b){ for ( int i=0;i<b.size();i++)a[i]=b[i];} template < typename T> void A2V(vector<T>&a, const T b[]){ for ( int i=0;i<a.size();i++)a[i]=b[i];} const double PI = acos (-1.0); const int INF = 1e9 + 7; /* -------------------------------------------------------------------------------- */ const int maxn = 1e5 + 7; const int M = 1e9; struct Node { int L, R, id; bool operator < ( const Node &that) const { return R < that.R; } Node( int L, int R, int id): L(L), R(R), id(id) {} Node() {} }; multiset<Node> S; int L[maxn], R[maxn]; pii node[maxn]; vector< int > G[maxn]; int main() { #ifndef ONLINE_JUDGE freopen ( "in.txt" , "r" , stdin); //freopen("out.txt", "w", stdout); #endif // ONLINE_JUDGE int T; cin >> T; while (T --) { int n; cin >> n; S.clear(); for ( int i = 0; i <= n; i ++) { G[i].clear(); } for ( int i = 0; i < n; i ++) { scanf ( "%d" , L + i); G[L[i]].pb(i); } for ( int i = 0; i < n; i ++) { scanf ( "%d" , R + i); node[i] = mp(L[i], R[i]); } for ( int i = 0; i < G[0].size(); i ++) { int id = G[0][i]; S.insert(Node(node[id].X, node[id].Y, id)); } vector< int > ans; vector< bool > vis(n); int cnt = 0; while (1) { multiset<Node>::iterator iter = S.lower_bound(Node(0, cnt, 0)); if (iter == S.end()) break ; ans.pb((*iter).id); vis[(*iter).id] = true ; S.erase(iter); cnt ++; for ( int i = 0; i < G[cnt].size(); i ++) { int id = G[cnt][i]; S.insert(Node(node[id].X, node[id].Y, id)); } } for ( int i = 0; i < n; i ++) { if (!vis[i]) ans.pb(i); } printf ( "%d\n" , cnt); for ( int i = 0; i < n; i ++) { printf ( "%d%c" , ans[i] + 1, i == n - 1? '\n' : ' ' ); } } return 0; } |