jzoj6367. 【NOIP2019模擬2019.9.25】工廠(factory)

在這裏插入圖片描述
在這裏插入圖片描述

賽時

⑧說了,比賽因爲T1搞自閉了。
草草無腦狀壓了一下,滾粗。

題解

其實這題真的很簡單。
首先,題目會給出特別特別多的區間。
那麼必定有幾個區間是不包含任何的區間的。(香蕉相交不算)
我們把這些區間拎出來,變成一個集合a。
而其他區間必定至少包含一個a集合中的區間。
把這些區間變成另一個集合b。

那麼我們可以發現一些小性質——
1、我們發現,可以先把a集合中的區間隨便放進若干個流水線中,只需保證工作時間>0即可。
2、其次,每個b集合中的區間要麼放入它所包含的a區間的流水線中,不做貢獻,要麼獨自一個放入一個新的集合中,產生自己的代價。

於是我們可以分開來做了。
首先我們設f[i][j]f_{[i][j]}表示當前把前i個a集合中的區間放入j個流水線的最大價值。
轉移顯然。O(n3)O(n^3)

那麼剩下的就可以隨意加入b集合了。
我們直接取出最大的幾個b區間,即可。

標程

#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <cctype>
using namespace std;
const int maxn=210;

int n,m,ga,gb,ans;
int x[maxn],y[maxn],ax[maxn],ay[maxn],bx[maxn],by[maxn];
int f[maxn][maxn],sum[maxn];
bool bz[maxn];

void qsortb(int l,int r)
{
	int i=l;int j=r;
	int m=by[(i+j)/2]-bx[(i+j)/2]+1;
	while (i<=j)
	{
		while (by[i]-bx[i]+1>m) i++;
		while (by[j]-bx[j]+1<m) j--;
		if (i<=j)
		{
			swap(bx[i],bx[j]);
			swap(by[i],by[j]);
			i++;j--;
		}
	}
	if (l<j) qsortb(l,j);
	if (r>i) qsortb(i,r); 
}

void qsorta(int l,int r)
{
	int i=l;int j=r;
	int m=ax[(i+j)/2];
	int m1=ay[(i+j)/2];
	while (i<=j)
	{
		while ((ax[i]<m) || (ax[i]==m && ay[i]<m1)) i++;
		while ((ax[j]>m) || (ax[j]==m && ay[j]>m1)) j--;
		if (i<=j)
		{
			swap(ax[i],ax[j]);
			swap(ay[i],ay[j]);
			i++;j--;
		}
	}
	if (l<j) qsorta(l,j);
	if (r>i) qsorta(i,r); 
}

int main()
{
	freopen("factory.in","r",stdin);
	freopen("factory.out","w",stdout);
	scanf("%d%d",&n,&m);	
	for (int i=1;i<=n;i++)
	{
		scanf("%d%d",&x[i],&y[i]);y[i]--;
	}
	memset(bz,false,sizeof(bz));
	for (int i=1;i<=n;i++)
	{
		bool pd=true;
		for (int j=1;j<=n;j++)
		{
			if (j!=i)
			{
				if (!bz[j] && x[i]<=x[j] && y[j]<=y[i])
				{
					pd=false;
					break;
				}
			}
		}
		if (pd==true)
		{
			ga++;
			ax[ga]=x[i];
			ay[ga]=y[i];
		}
		else
		{
			gb++;
			bx[gb]=x[i];
			by[gb]=y[i];
			bz[i]=true;
		}
	}
	qsorta(1,ga);
	memset(f,128,sizeof(f));
	f[0][0]=0;
	for (int i=0;i<=ga;i++)
	{
		for (int k=0;k<=min(i,m);k++)
		{
			for (int j=i+1;j<=ga;j++)
			{
				if (f[i][k]>=0)
				if (ay[i+1]-ax[j]+1>0)
				{
					f[j][k+1]=max(f[j][k+1],f[i][k]+ay[i+1]-ax[j]+1);
				}
			}
		}
	}
	qsortb(1,gb);
	for (int i=1;i<=n;i++)
	{
		sum[i]=sum[i-1]+by[i]-bx[i]+1;
	}
	for (int i=0;i<=m;i++)
	{
		ans=max(ans,f[ga][m-i]+sum[i]);
	}
	printf("%d\n",ans);
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章