Toys KickStart2020E轮

https://codingcompetitions.withgoogle.com/kickstart/round/000000000019ff47/00000000003bede9#problem

First consider the infinite situation, suppose sum is the sum of e[i], then when all toys satisfy sum-e[i]>=r[i], it can be infinite

Then we first assume that there is an infinite situation, and think about how to find the minimum number of items to delete

It can be found that the condition is sum>=e[i]+r[i], then if he does not meet the largest e[i]+r[i], he must be deleted. Why not delete other illegal ones? Because even if you delete others, only the sum decreases, and e[i]+r[i] is unchanged, he still has to delete it, so we delete the largest one first, and delete it until it can’t be deleted. If there is no Delete all, then it is infinite.

Then we consider the case of the last deletion and find the maximum value

First consider that the first round is definitely playable, because I have not played it yet, so sum=e[1]+...e[n], the problem lies in the second round, we set the second round time as cur , In order to consider whether to enter, if e[i]+r[i]<=sum, it means you can enter, then q.push(a[i]),cur+=e[i], otherwise it means the i-th toy Must be discarded, because our sum assumes that only the first i toys are processed, and the following toys are all in the queue, indicating that the sum decreases with the processing, then e[i]+r[i]>sum It cannot be changed, so it must be discarded. However, at this time we have caused the sum to decrease, so some of the previously added queues may also be discarded. The while loop is discarded. After discarding, it is enough to judge whether sum+cur is greater than the known best answer.

#include<bits/stdc++.h>
#define pb push_back
using namespace std;
typedef long long ll;

const int maxl=3e5+10;

int n,m,cas,k,cnt,tot,ans;ll ansmx;
int e[maxl],r[maxl];
struct node
{
	int val,id;
	bool operator < (const node &b)const
	{
		if(val==b.val)
			return id<b.id;
		return val<b.val;
	}
}a[maxl];
priority_queue<node> q;
char s[maxl];
bool in[maxl]; 

inline void prework()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d%d",&e[i],&r[i]);
		a[i]=node{e[i]+r[i],i};
	}
} 

inline void mainwork()
{
	ll sum=0,cur;int del;
	while(!q.empty())
		q.pop();
	for(int i=1;i<=n;i++)
		sum+=e[i],q.push(a[i]);
	while(!q.empty())
	{
		if(q.top().val<=sum)
			break;
		else
			sum-=e[q.top().id],q.pop();
	}
	if(!q.empty())
	{
		ans=n-q.size();ansmx=-1;
		return;
	}
	while(!q.empty())
		q.pop();
	del=0;sum=0;node d;
	for(int i=1;i<=n;i++)
		sum+=e[i],in[i]=true;
	cur=0;ansmx=sum;ans=0;
	for(int i=1;i<=n;i++)
	if(in[i])
	{
		if(e[i]+r[i]<=sum)
		{
			cur+=e[i];
			q.push(a[i]);
		}
		else
		{
			del++;sum-=e[i];
			while(!q.empty())
			{
				if(q.top().val<=sum)
					break;
				else
				{
					d=q.top();q.pop();
					sum-=e[d.id];
					cur-=e[d.id];
					++del;
				}
			}	
		}
		if(sum+cur>ansmx)
			ansmx=sum+cur,ans=del;
	}
}

inline void print()
{
	printf("Case #%d: ",cas);
	if(ansmx<0)
		printf("%d INDEFINITELY\n",ans);
	else	
		printf("%d %lld\n",ans,ansmx);
}

int main()
{
	int t=1;
	scanf("%d",&t);
	for(cas=1;cas<=t;cas++)
	{
		prework();
		mainwork();
		print();
	}
	return 0;
}

 

Guess you like

Origin blog.csdn.net/liufengwei1/article/details/108191990