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;
}