【DP+贪心】能量石

题面https://www.acwing.com/problem/content/736/

分析:

这是一道基于贪心和DP的题目,可以从分析两个相邻物品的顺序入手:

对相邻的两个物品 i, i+1
记取到它们的时候(假设它们的能量在这个过程中都没有耗尽)它们的属性是: si,ei,li;si+1,ei+1,li+1

运用类似的排序思想的题目还有:https://www.acwing.com/problem/content/description/127/

如果按照先 i, 然后 i+1 的顺序选,那么应有:

ei+ei+1sili+1>ei+1+eisi+1li

即:sili+1<si+1li ,从中我们得到了贪心的取物品顺序。

然后就转化为01背包问题了,注意,这里的状态 fj 表示是若时间恰为 j 所能得到的最大价值,如果不这样表示则无法正确处理时间导致的能量损失问题。

代码

#include<bits/stdc++.h>
using namespace std;

const int N=110, M=1e4+5;

struct node{
    int s,e,l;
}a[N];

bool cmp(node a,node b){
    return a.s*b.l<a.l*b.s;
}
int T,tot;
int n;

int f[M];

int main(){
    cin>>T;
    while(T--){
        
        memset(f,0xcf,sizeof f);
        f[0]=0;
        
        cin>>n;
        
        int t=0; //总时间
        for(int i=1;i<=n;i++){
            cin>>a[i].s>>a[i].e>>a[i].l;
            t+=a[i].s;
        }
        
        sort(a+1,a+1+n,cmp);
        
        for(int i=1;i<=n;i++){
            int s=a[i].s,e=a[i].e,l=a[i].l;
            for(int j=t;j>=s;j--){
                f[j]=max(f[j],max(f[j-s]+e-(j-s)*l,0));
            }
        }
        
        int res=0;
        for(int i=0;i<=t;i++) res=max(res,f[i]);
        
        printf("Case #%d: %d\n",++tot,res);
    }
    return 0;
}
posted @   HinanawiTenshi  阅读(87)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示