洛谷 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;
}

浙公网安备 33010602011771号