社区讨论

为何这种贪心不对

P11268【MX-S5-T2】买东西题参与者 2已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@mdmha83l
此快照首次捕获于
2025/07/28 10:17
7 个月前
此快照最后确认于
2025/11/04 03:37
4 个月前
查看原帖
我想的贪心是,物品按照 aia_i 从小到大排序,优惠券按照 wiw_i 从大到小排序,一张优惠券起的实际作用是 wj+biaiw_j+b_i-a_i,让作用最大相当于找最小的 f(i)=aibif(i)=a_i-b_i。一张优惠券可以使用的物品是一个后缀,我使用 线段树 找这个后缀的最小 ff,找到后标记上为 inf,复杂度单 log。
但是小样例过了大样例都没过。这种贪心为何不正确?
CPP
#include<bits/stdc++.h>
#define lc(x) x << 1
#define rc(x) x << 1 | 1
using namespace std;
typedef long long ll;
const int MAXN = 1e6 + 10;
const ll inf = 0x3f3f3f3f3f3f3f3f;
inline ll read(){
	ll x = 0, f = 1; char c = getchar();
	while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
	while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
	return x * f;
}

int n, m, id[MAXN];
int az[MAXN];
struct SGTNode{
	ll val, pos;
} sgt[MAXN<<2];
struct Node1{
	ll x, y;
	bool operator < (const Node1 &f) const {return this->x < f.x;}
	bool operator > (const Node1 &f) const {return this->x > f.x;}
	bool operator == (const Node1 &f) const {return this->x == f.x;}
	// x = a       x = w
	// y = b       y = v
}a[MAXN], b[MAXN];

bool cmp1(Node1 g, Node1 h){
	return g.x < h.x;
} 
bool cmp2(Node1 g, Node1 h){
	if(g.x != h.x)
		return g.x > h.x;
	return g.y > h.y;
} 

SGTNode qmin(SGTNode g, SGTNode h){
	if(h.val < g.val)
		return h;
	return g;
}

void pushup(int u){
	sgt[u] = qmin(sgt[lc(u)], sgt[rc(u)]);
}

inline bool in(int tL, int tR, int l, int r){
	return l <= tL && tR <= r;
}
inline bool out(int tL, int tR, int l, int r){
	return l > tR || tL > r; 
}


void build(int u, int tL, int tR){
	if(tL == tR){
		sgt[u].val = a[tL].x-a[tL].y;
		sgt[u].pos = tL;
		id[tL] = u;
		return ;
	}
	int mid = (tL+tR) >> 1;
	build(lc(u), tL, mid);
	build(rc(u), mid+1, tR);
	pushup(u); 
}

SGTNode query(int u, int tL, int tR, int l, int r){
	if(in(tL, tR, l, r)) 
		return sgt[u];
	if(out(tL, tR, l, r))
		return (SGTNode){inf, -1};
	int mid = (tL+tR) >> 1;
	return qmin(query(lc(u), tL, mid, l, r), query(rc(u), mid+1, tR, l, r));
}

void update(int pos){
	int u = id[pos];
	sgt[u].val = inf;
	u >>= 1;
	while(u){
		pushup(u);
		u >>= 1;
	}
}

int main(){
//	freopen("buy4.in", "r", stdin);
	memset(sgt, 0x3f, sizeof(sgt));
	n = read(), m = read();
	for(int i = 1; i <= n; i++)
		a[i].x = read(), a[i].y = read();
	for(int i = 1; i <= m; i++)
		b[i].x = read(), b[i].y = read();
	sort(a+1, a+1+n, cmp1);
	sort(b+1, b+1+m, cmp2);
	build(1, 1, n);
	for(int i = 1; i <= m; i++){
		int id = lower_bound(a+1, a+1+n, b[i]) - a;
		SGTNode t = query(1, 1, n, id, n);
		if(t.val > b[i].y) continue;
		az[t.pos] = i;
		update(t.pos);
//		cout << "debug : " << i << ' ' << t.pos << endl;
	}
	ll ans = 0;
	for(int i = 1; i <= n; i++){
		if(az[i] == 0) ans += a[i].y;
		else ans += a[i].x - b[az[i]].y;
	}
	cout << ans;
	return 0;
}

回复

2 条回复,欢迎继续交流。

正在加载回复...