P1844 阅览室
此题现有题解较为冗长,因此前来贡献一发最短解。
首先正常的思路是直接按题意模拟。即:
- 枚举当前时刻 \(T\)
- 对于每个人,标记该时刻想要拿到的书
- 根据题目的要求判断冲突情况
- 对书进行分配
实现起来复杂的地方主要在处理冲突上,考虑从这方面简化代码。
我们知道,时刻为 \(t\) 时第 \(i\) 个人已经等待的时间与他即将读哪本书无关,只与这个人开始等待的时刻有关。
故设 \(last_i\) 为第 \(i\) 个人开始等待(即读完上一本书)的时刻。则把人按照 \(last\) 的值为第一关键字,到达时间的值为第二关键字进行升序排列,不难证明对于同一本书,等待时间更长的人一定先被计算到。
既然已经说到这步,我们直接按把人排序后的先后顺序分配书就可以避免冲突问题了。
可能比其他做法多了个排序的 log,但对于此题数据范围依然绰绰有余。
AC code:
#include<bits/stdc++.h>
using namespace std;
const int N=1005;
int T,n;
struct node{
	int arr,k,ls; 
	int s[10],t[10],flg[10];
}a[N];
bool cmp(node x,node y){
	if(x.ls==y.ls) return x.arr<y.arr;
	else return x.ls<y.ls;
}
int ans,bk[N];
int main()
{
	scanf("%d%d",&T,&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d%d",&a[i].arr,&a[i].k);a[i].arr++;
		for(int j=1;j<=a[i].k;j++) scanf("%d%d",&a[i].s[j],&a[i].t[j]);
		a[i].ls=a[i].arr;
	}
	for(int t=1;t<=T;t++)
	{
		sort(a+1,a+n+1,cmp);
		for(int i=1;i<=n;i++)
		{
			if(a[i].ls>t||a[i].arr>t) continue; 
			for(int k=1;k<=a[i].k;k++)
			{
				if((bk[a[i].s[k]]<=t)&&(!a[i].flg[k]))
				{
					ans++;a[i].flg[k]=1;
					a[i].ls=bk[a[i].s[k]]=t+a[i].t[k];
					break;
				}
			}
		}
	}
	cout<<ans<<endl;
	return 0;
}
本文来自博客园,作者:樱雪喵,转载请注明原文链接:https://www.cnblogs.com/ying-xue/p/16714243.html

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号