一堆杂题混刷

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;
}
posted @ 2025-09-21 18:20  MistyPost  阅读(9)  评论(0)    收藏  举报