# Greedy ---- greedy + STL maintenance + partition set L. Neo Robin Hood (good question)

Keywords: Algorithm

## Main idea of the title:

You are Robin Hood who robbed the rich to help himself. There are n rich people. The ith person has m[i] yuan of wealth. It takes p[i] yuan to buy him. You can choose from everyone. 1. Rob him and you get m[i] yuan. 2. Don't operate on him. 3. Buy him for p[i] yuan and he will absolve you of a robbery. You have a strange goal: the more people you rob, the better, but every crime you commit must be excused.

Grab k people and buy off other k people. The money you grab should be enough to buy off and maximize k.

## Problem solving ideas:

1. First, we found that if j < k j<k J < K and k k If k is legal, then j j j is definitely OK, so the answer is that there is a dichotomy?

2. Let's take a look at the assumption that now we have chosen 2 ∗ k 2*k 2 * k people. Now we can only exchange the elements in two sets e g : steal j buy i → steal i buy j eg: steal j buy i\rightarrow steal i buy j eg: steal j and buy i → steal i and buy j

3. We know S S S set is a stolen set, T T The set of T is the set bought, then S = ∑ m i , P = ∑ p j S=\sum m_i,P=\sum p_j S=∑mi​,P=∑pj​

4. Then the legal collection is S − T ≥ 0 S-T\ge0 S−T≥0

5. We just make it easier to adjust and change between segments S − T ≥ 0 S-T\ge0 S−T≥0

6. exchange i and j i and j i and j → \rightarrow → ( S − m i + m j ) − ( T − p j + p i ) ≥ 0 (S-m_i+m_j)-(T-p_j+p_i)\ge0 (S−mi​+mj​)−(T−pj​+pi​)≥0

7. Simplified S − T + ( m j + p j ) − ( m i + p i ) ≥ 0 S-T+(m_j+p_j)-(m_i+p_i)\ge0 S−T+(mj​+pj​)−(mi​+pi​)≥0

8. According to the above formula, we must be greedy to steal m i + p i m_i+p_i mi + pi ， big people are the best!!

9. Now we can follow m i + p i m_i+p_i mi + pi ， sort, but how k k What about k people?
That is, we know that stealing must be in the front and buying the back. Then there must be a boundary line between Zhe and zhe. Then we can enumerate and judge the boundary line.

10. We from [ 1 , x ] [1,x] Steal from [1,x] [ x + 1 , n ] [x+1,n] [x+1,n] buy it inside. Just judge it

## AC code

#include <bits/stdc++.h>
#define mid ((l + r + 1) >> 1)
#define Lson rt << 1, l , mid
#define Rson rt << 1|1, mid + 1, r
#define ms(a,al) memset(a,al,sizeof(a))
#define log2(a) log(a)/log(2)
#define lowbit(x) ((-x) & x)
#define IOS std::ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define INF 0x3f3f3f3f
#define LLF 0x3f3f3f3f3f3f3f3f
#define f first
#define s second
#define endl '\n'
using namespace std;
const int N = 2e6 + 10, mod = 1e9 + 9;
const int maxn = 500010;
const long double eps = 1e-5;
const int EPS = 500 * 500;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
typedef pair<double,double> PDD;
template<typename T> void read(T &x) {
x = 0;char ch = getchar();ll f = 1;
while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();}
while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f;
}
template<typename T, typename... Args> void read(T &first, Args& ... args) {
}
struct node {
int mi, pi;
bool operator < (const node & a){
if(mi + pi == a.mi + a.pi) return mi > a.mi;
else return mi + pi > a.mi + a.pi;
}
}e[maxn];
int n;
ll frontmax[maxn], bemin[maxn];
bool check(int pe) {
if(!pe) return 1;
ms(frontmax,0); // Steal big
multiset<int> premax;
priority_queue<int> aftmin;
ll sum = 0;
for(int i = 1; i <= n; ++ i) {
if(premax.size() < pe) {// pe before dynamic maintenance
sum += e[i].mi;
premax.insert(e[i].mi);
frontmax[i] = sum;
continue;
}
if(*premax.begin() < e[i].mi) {
frontmax[i] = frontmax[i-1] + e[i].mi - (*premax.begin());
premax.erase(premax.begin());
premax.insert(e[i].mi);
}
else frontmax[i] = frontmax[i-1];
}

sum = 0;
for(int i = n; i >= 1; -- i) {
if(aftmin.size() < pe) {
sum += e[i].pi;
aftmin.push(e[i].pi);
bemin[i] = sum;
continue;
}
if(aftmin.top() > e[i].pi) {
bemin[i] = bemin[i+1] + e[i].pi - aftmin.top();
aftmin.pop();
aftmin.push(e[i].pi);
} else bemin[i] = bemin[i+1];
}

for(int i = pe; i <= n - pe; ++ i)
if(frontmax[i] >= bemin[i+1])
return 1;
return 0;
}

int main() {
IOS;
cin >> n;
for(int i = 1; i <= n; ++ i) cin >> e[i].mi;
for(int i = 1; i <= n; ++ i) cin >> e[i].pi;
sort(e+1,e+1+n);
int l = 0, r = n / 2;
while(l < r) {
if(check(mid)) l = mid;
else r = mid - 1;
}
cout << l;
return 0;
}


Posted by jason.carter on Wed, 06 Oct 2021 11:49:14 -0700