Luogu2869 [USACO07DEC]美食的食草动物Gourmet Grazers (贪心,二分,数据结构优化)

贪心
考场上因无优化与卡常T掉的(n log(n))

//#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define R(a,b,c) for(register int  a = (b); a <= (c); ++ a)
#define nR(a,b,c) for(register int  a = (b); a >= (c); -- a)
#define Max(a,b) ((a) > (b) ? (a) : (b))
#define Min(a,b) ((a) < (b) ? (a) : (b))
#define Fill(a,b) memset(a, b, sizeof(a))
#define Abs(a) ((a) < 0 ? -(a) : (a))
#define Swap(a,b) a^=b^=a^=b
#define ll long long

#define ON_DEBUG

#ifdef ON_DEBUG

#define D_e_Line printf("

----------

")
#define D_e(x)  cout << #x << " = " << x << endl
#define Pause() system("pause")
#define FileOpen() freopen("in.txt","r",stdin);

#else

#define D_e_Line ;
#define D_e(x)  ;
#define Pause() ;
#define FileOpen() ;

#endif

struct ios{
    template<typename ATP>ios& operator >> (ATP &x){
        x = 0; int f = 1; char c;
        for(c = getchar(); c < '0' || c > '9'; c = getchar()) if(c == '-')  f = -1;
        while(c >= '0' && c <= '9') x = x * 10 + (c ^ '0'), c = getchar();
        x*= f;
        return *this;
    }
}io;
using namespace std;

const int N = 100007;

struct Day{
	long long cost, taste;
	bool operator < (const Day &com) const{
		if(taste != com.taste) return taste > com.taste;
		return cost > com.cost;
	}
}day[N];
struct Food{
	long long cost, taste;
	bool operator < (const Food &com) const{
		if(cost != com.cost) return cost < com.cost;
		return taste < com.taste;
	}
}food[N];

int n, m;
inline int FindFood(int price){
	int l = 1, r = m;
	while(l <= r){
		int mid = (l + r) >> 1;
		if(food[mid].cost >= price)
			r = mid - 1;
		else
			l = mid + 1;
	}
	return l;
}
int vis[N];

int main(){
freopen("snack.in", "r", stdin);
freopen("snack.out", "w", stdout);
	io >> n >> m;
	R(i,1,n){
		io >> day[i].cost >> day[i].taste;
	}
	
	R(i,1,m){
		io >> food[i].cost >> food[i].taste;
	}
	
	if(m < n){
		printf("-1");
		return 0;
	}
	
	sort(day + 1, day + n + 1);
	sort(food + 1, food + m + 1);
	
	long long ans = 0;
	R(i,1,n){
		int pos = FindFood(day[i].cost);
		while(vis[pos] == true) ++pos;
		if(pos > m){
			printf("-1"); return 0;
		}
		int flag = 0;
		R(j,pos,m){
			if(vis[j]) continue;
			if(food[j].taste >= day[i].taste){
				vis[j] = true;
				ans += food[j].cost;
				flag = 1;
				break;
			}
		}
		if(!flag){
			printf("-1"); return 0;
		}
	}
	
	printf("%lld", ans);
	
	return 0;
}
/*
one money raise
one taste down
4 7
1 1
2 3
1 4
4 2
3 2
2 1
4 3
5 2
5 4
2 6
4 4
*/

正解用数据结构,或STL水

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define R(a,b,c) for(register int  a = (b); a <= (c); ++ a)
#define nR(a,b,c) for(register int  a = (b); a >= (c); -- a)
#define Max(a,b) ((a) > (b) ? (a) : (b))
#define Min(a,b) ((a) < (b) ? (a) : (b))
#define Fill(a,b) memset(a, b, sizeof(a))
#define Abs(a) ((a) < 0 ? -(a) : (a))
#define Swap(a,b) a^=b^=a^=b
#define ll long long

#define ON_DEBUG

#ifdef ON_DEBUG

#define D_e_Line printf("

----------

")
#define D_e(x)  cout << #x << " = " << x << endl
#define Pause() system("pause")
#define FileOpen() freopen("in.txt","r",stdin);

#else

#define D_e_Line ;
#define D_e(x)  ;
#define Pause() ;
#define FileOpen() ;

#endif

struct ios{
    template<typename ATP>ios& operator >> (ATP &x){
        x = 0; int f = 1; char c;
        for(c = getchar(); c < '0' || c > '9'; c = getchar()) if(c == '-')  f = -1;
        while(c >= '0' && c <= '9') x = x * 10 + (c ^ '0'), c = getchar();
        x*= f;
        return *this;
    }
}io;
using namespace std;
#include <set>

const int N = 100007;

multiset<int> st;
pair<int,int> day[N], food[N];
int main(){
//FileOpen();
    int n,m;
    io >> n >> m;
    R(i,1,n){
    	io >> day[i].second >> day[i].first;
    }
    R(i,1,m){
    	io >> food[i].second >> food[i].first;
    }
    
    sort(day + 1, day + n + 1);
    sort(food + 1, food + m + 1);
    
    int j = m;
    long long ans = 0;
    nR(i,n,1){
        while(j && food[j].first >= day[i].first){
        	st.insert(food[j].second);
			--j;
        }
        multiset<int>::iterator it = st.lower_bound(day[i].second);

        if(it == st.end()){
            printf("-1"); return 0;
        }
        
        ans += *it;
        st.erase(it);
    }
    
    printf("%lld", ans);
    return 0;
}

原文地址:https://www.cnblogs.com/bingoyes/p/11244252.html