洛谷 P1833 樱花 题解

题目链接

洛谷 P1833 樱花

混合背包模板题。

Tip:题目中 \(T_i\) 单位为分钟(\(\operatorname{min}\))。

思路分析

这题其实是将之前 0-1 背包、完全背包、多重背包三种类型的题拼凑到一起。由于 0-1 背包其实就是每件物品数量都为 \(1\) 的多重背包,所以只需把完全背包和多重背包的代码放一起即可。

代码呈现

首先使用 scanf() 读入时间,求差并转换为分钟。当 p[i]==0 时为完全背包,执行完全背包代码;当 p[i]!=0 时为 0-1 背包/多重背包,执行多重背包的代码。

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

const int N=10010,T=1010;
int hs,ms,he,me,n;
int t[N],c[N],p[N],dp[T];

int main(){
    scanf("%d:%d %d:%d %d",&hs,&ms,&he,&me,&n);
    for (int i=1;i<=n;++i) scanf("%d%d%d",t+i,c+i,p+i);
    int m=(he-hs)*60+me-ms;
    for (int i=1;i<=n;++i){
        if (p[i]==0){
            for (int j=t[i];j<=m;++j) dp[j]=max(dp[j],dp[j-t[i]]+c[i]);
        }else{
            int x=log2(p[i]);
            for (int j=1<<(x-1);j>0;j>>=1){
                for (int k=m;k>=j*t[i];--k) dp[k]=max(dp[k],dp[k-j*t[i]]+j*c[i]);
            }
            int y=p[i]-(1<<x)+1;
            if (y!=0){
                for (int j=m;j>=y*t[i];--j) dp[j]=max(dp[j],dp[j-y*t[i]]+y*c[i]);
            }
        }
    }
    printf("%d",dp[m]);
    return 0;
}
posted @ 2025-12-22 16:58  CodingJuRuo  阅读(0)  评论(0)    收藏  举报