洛谷 P11268 【MX-S5-T2】买东西题 做题记录

我不会贪心。

\(a\) 元的物品有 \(b\) 元的折扣,就相当于 \(a\) 元的物品有一张 \(a-b\) 元的优惠券。
因为一张优惠券是满 \(w\) 元才可以用,所以可以用的物品在价格 \(a\) 上是一段区间 \([a,\inf]\)
有一个很朴素的想法是,将每一个物品最多能省多少钱先弄出来,然后用优惠券想办法把省的最小的钱换成优惠券。
先将物品和优惠券按满多少可以有优惠排序,再枚举优惠券,最后就是按照上面说的逐步加进去就好了。
想要快速求出最小值可以用优先队列,如果到最后还用不到优惠券的记得把打得折加进去。
时间复杂度 \(O(n \log n)\)

点击查看代码
#include<bits/stdc++.h>
#define int ll
#define mem(a,b) memset((a),(b),sizeof(a))
#define m0(a) memset((a),0,sizeof(a))
#define lb(x) ((x)&-(x))
#define lc(x) ((x)<<1)
#define rc(x) (((x)<<1)|1)
#define pb(G,x) (G).push_back((x))
#define For(a,b,c) for(int a=(b);a<=(c);a++)
#define Rep(a,b,c) for(int a=(b);a>=(c);a--)
#define in1(a) a=read()
#define in2(a,b) a=read(), b=read()
#define in3(a,b,c) a=read(), b=read(), c=read()
#define inn(i,n,a) For(i,1,n) a[i]=read();

#define ll long long
#define i128 __int128

using namespace std;
inline int read() {
	int xx= 0;int f= 1;
	char c = getchar();
	while(c<'0'||c>'9') { 
		if(c=='-') f= -1;
		c= getchar();
	}
	while(c>='0'&&c<='9') {
		xx= (xx<<1)+(xx<<3)+(c^48);
		c= getchar();
	}
	return xx*f;
}
#define maxn 1000050
int n,m;
struct node {
	int x,y;
}a[maxn],b[maxn];
bool cmp(node a,node b) {
	return a.x==b.x?a.y>b.y:a.x>b.x;
}
int res=0;
signed main() {
	in2(n,m);
	For(i,1,n) {
		int x,y;
		in2(x,y);
		a[i].x=x,a[i].y=x-y;
		res+=a[i].x;
	}
	For(i,1,m) {
		in2(b[i].x,b[i].y);
	}
	int i=1;
	sort(a+1,a+n+1,cmp);
	sort(b+1,b+m+1,cmp);
	priority_queue<int,vector<int>,greater<int> > q;
	For(j,1,m){
		while(i<=n&&a[i].x>=b[j].x) q.push(a[i].y),i++;
		if(q.size()&&q.top()<b[j].y) {
			q.pop();
			q.push(b[j].y);
		}
	}
	while(i<=n) q.push(a[i].y),i++;
	while(q.size()) res-=q.top(),q.pop();
	cout<<res;
}
posted @ 2024-11-09 14:05  coding_goat_qwq  阅读(51)  评论(0编辑  收藏  举报