一堆杂题混刷
P6359(绿,DP)
题意
有 \(n\) 台计算机,每台由三元组 \((c_i, f_i, v_i)\) 描述,分别表示核心数、时钟频率、购买价格。
有 \(m\) 个客户订单,每个订单由三元组 \((C_j, F_j, V_j)\) 描述,分别表示所需核心数、最低频率要求、支付金额。
你需要选择购买一部分计算机,并接受一部分订单,使得:
- 每个被接受的订单 \(j\),都能被分配恰好 \(C_j\) 个核心,这些核心来自已购买的计算机,且每个核心的频率 \(\ge F_j\);
- 同一核心不能分配给多个订单;
- 利润 = 所有被接受订单的 \(V_j\) 之和 - 所有被购买计算机的 \(v_i\) 之和 最大化。
输出最大利润。
思路
自己一点想不出来,其实就是先按照频率从大到小排序,然后把计算机和客户放到一起做01DP。这样就可以保证跑到客户时频率需求一定是满足的。
然后频率相同时,遵循“先买后卖”的原则排序就好。
然后?就没有然后了。
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll n,m,tot;
ll f[500005];
struct nood{
ll c,f,v;
}e[1000000];
bool cmp(nood x,nood y){
if(x.f!=y.f){
return x.f>y.f;
}
return x.v<y.v;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
tot++;
cin>>e[i].c>>e[i].f>>e[i].v;
e[tot].v=-e[tot].v;
}
cin>>m;
for(int i=1;i<=m;i++){
tot++;
cin>>e[tot].c>>e[tot].f>>e[tot].v;
}
sort(e+1,e+tot+1,cmp);
for(int i=0;i<=500000;i++){
f[i]=-1e18;
}
f[0]=0;
ll ls=0;
for(int i=1;i<=tot;i++){
if(e[i].v<0){
for(int j=ls;j>=0;j--){
f[j+e[i].c]=max(f[j+e[i].c],f[j]+e[i].v);
}
ls+=e[i].c;
}
else{
for(int j=0;j+e[i].c<=ls;j++){
f[j]=max(f[j],f[j+e[i].c]+e[i].v);
}
}
}
ll ans=0;
for(int i=0;i<=500000;i++){
ans=max(ans,f[i]);
}
cout<<ans;
return 0;
}
可以自由转载

浙公网安备 33010602011771号