Luogu P6359 [CEOI2018]Cloud computing

SB题

把所有计算机和订单都按照\(c_i\)排序,相同时规定计算机排在订单前面

容易发现此时对于一个订单,只有它前面的计算机可以为它提供处理器

直接大力背包,\(f_{i,x}\)表示前\(i\)个处理完之后剩下\(x\)个处理器的最大利润,显然前面这一维可以去掉

稍微卡下上下界就跑得飞快,复杂度\(O(n^2c_i)\)

#include<cstdio>
#include<algorithm>
#define RI register int
#define CI const int&
using namespace std;
const int N=2005;
const long long INF=1e18;
struct element
{
	int c,f,v,tp;
	friend inline bool operator < (const element& A,const element& B)
	{
		return A.f!=B.f?A.f>B.f:A.tp<B.tp;
	}
}a[N<<1]; int n,m,lim; long long f[N*50],ans;
int main()
{
	RI i,j; for (scanf("%d",&n),i=1;i<=n;++i)
	scanf("%d%d%d",&a[i].c,&a[i].f,&a[i].v);
	for (scanf("%d",&m),i=1;i<=m;++i)
	scanf("%d%d%d",&a[n+i].c,&a[n+i].f,&a[n+i].v),a[n+i].tp=1;
	for (i=0;i<=n*50;++i) f[i]=-INF;
	for (f[0]=0,sort(a+1,a+n+m+1),i=1;i<=n+m;++i)
	if (a[i].tp) for (j=a[i].c;j<=lim;++j) f[j-a[i].c]=max(f[j-a[i].c],f[j]+a[i].v);
	else for (j=lim,lim+=a[i].c;~j;--j) f[j+a[i].c]=max(f[j+a[i].c],f[j]-a[i].v);
	for (i=0;i<=lim;++i) ans=max(ans,f[i]); return printf("%lld",ans),0;
}
posted @ 2020-12-02 21:12  空気力学の詩  阅读(154)  评论(0编辑  收藏  举报