codeforces1203 F1 Complete the Projects (easy version)

传送门:http://codeforces.com/problemset/problem/1203/F1

参考博客:https://blog.csdn.net/evilwind2000/article/details/99542823?utm_source=app

分两种情况:b>=0的时候十分简单,只要一直取a最小的就行了

b<0的时候,一直取 a+b 较大的,只需证明 a1+b1>a2+b2时候,如果 1 2 这样的顺序不行,那么2 1 也不行

(1)如果r<a1 || r+b1+b2<0  显然不行 

(2)如果r+b1<a2 ,那么由a1+b1>a2+b2,得b2<a1-a2+b1,则r+b2<r+b1+a1-a2<a2+a1-a2=a1,那么肯定是不行的。

#include<bits/stdc++.h>
#define maxl 300010
 
using namespace std;
 
int n,m,ans,r,cnt;
struct node
{
	int a,b;
	bool operator < (const node &b)const
	{
		return this->b<b.b;
	}
}a[maxl],c[maxl];
char s[maxl];
vector <node> b[maxl];
priority_queue <node> q;
bool in[maxl];
 
inline void prework()
{
	scanf("%d",&n);
	scanf("%d",&r);
	for(int i=1;i<=n;i++)
	{
		scanf("%d%d",&a[i].a,&a[i].b);
		if(a[i].a<=r)
			q.push(a[i]);
		else
			b[a[i].a].push_back(a[i]);
	}
}
 
inline bool cmp(const node &x,const node &y)
{
	if(x.a+x.b==y.a+y.b)
		return x.a<y.a;
	return x.a+x.b<y.a+y.b;
}
 
inline void mainwork()
{
	node d;int sum=0;ans=0;
	while(!q.empty())
	{
		d=q.top();
		if(d.b<0)
			break;
		q.pop();sum++;
		for(int i=r+1;i<=r+d.b && r+d.b<maxl;i++)
		{
			int l=b[i].size();
			for(int j=0;j<l;j++)
				q.push(b[i][j]);
		}
		r+=d.b;
	}
	if(sum==n)
	{
		ans=1;
		return;
	}
	while(!q.empty())
		c[++cnt]=q.top(),q.pop();
	sort(c+1,c+1+cnt,cmp);
	for(int i=cnt;i>=1;i--)
	if(c[i].a<=r)
		r+=c[i].b,sum++;
	else
	{
		ans=0;
		return;
	}
	if(r>=0 && sum==n)
		ans=1;
}
 
inline void print()
{
	if(ans)
		puts("YES");
	else
		puts("NO");
}
 
int main()
{
	int t=1;
	//scanf("%d",&t);
	for(int i=1;i<=t;i++)
	{ 
		prework();
		mainwork();
		print();
	}
	return 0;
}

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值