目录
显示
题目链接
题解
乍一看购买电脑和接单是两个截然不同的操作,但事实上这两个操作可以同一为同一种操作。
购买电脑可以认为是消耗一些钱(即收益为负)购买一定数量的核心;而接单则是消耗一些核心获得一定收益。最终的目标是在核心数非负的前提下,使得收益最大化。
这显然是一个背包的模型。
问题在于怎样确保接单消耗的核心都符合频率要求呢?我们可以将按频率降序进行排序,这样对第 \(i\) 个物品进行转移的时候,就只会用到频率不低于当前物品要求的核心了。
#include <cstring> #include <iostream> #include <algorithm> using namespace std; struct node { int c,f,v,type; }a[4005]; long long f[100005]; bool cmp(const node&a,const node&b) { return a.f>b.f||(a.f==b.f&&a.type<b.type); } int main() { int n,m; cin>>n; for(int i=1;i<=n;i++) { cin>>a[i].c>>a[i].f>>a[i].v; a[i].type=0; } cin>>m; for(int i=n+1;i<=n+m;i++) { cin>>a[i].c>>a[i].f>>a[i].v; a[i].type=1; } sort(a+1,a+n+m+1,cmp); int sc=0; memset(f,191,sizeof(f)); f[0]=0; for(int i=1;i<=n+m;i++) { int t=a[i].type,c=a[i].c,v=a[i].v; if(!t) { for(int j=sc;j>=0;j--) f[j+c]=max(f[j+c],f[j]-v); sc+=c; } else { for(int j=c;j<=sc;j++) f[j-c]=max(f[j-c],f[j]+v); } } long long ans=0; for(int i=0;i<=sc;i++) ans=max(ans,f[i]); cout<<ans<<endl; return 0; }