P1833 樱花(二进制优化背包)
题目背景
《爱与愁的故事第四弹·plant》第一章。
题目描述
爱与愁大神后院里种了 nn 棵樱花树,每棵都有美学值 C_iCi。爱与愁大神在每天上学前都会来赏花。爱与愁大神可是生物学霸,他懂得如何欣赏樱花:一种樱花树看一遍过,一种樱花树最多看 A_iAi 遍,一种樱花树可以看无数遍。但是看每棵樱花树都有一定的时间 T_iTi。爱与愁大神离去上学的时间只剩下一小会儿了。求解看哪几棵樱花树能使美学值最高且爱与愁大神能准时(或提早)去上学。
输入格式
共 n+1n+1行:
第 11 行:现在时间 T_sTs(几时:几分),去上学的时间 T_eTe(几时:几分),爱与愁大神院子里有几棵樱花树 nn。这里的 T_sTs,T_eTe 格式为:hh:mm
,其中 0 \leq hh \leq 230≤hh≤23,0 \leq mm \leq 590≤mm≤59,且 hh,mm,nhh,mm,n 均为正整数。
第 22 行到第 n+1n+1 行,每行三个正整数:看完第 ii 棵树的耗费时间 T_iTi,第 ii 棵树的美学值 C_iCi,看第 ii 棵树的次数 P_iPi(P_i=0Pi=0 表示无数次,P_iPi 是其他数字表示最多可看的次数 P_iPi)。
输出格式
只有一个整数,表示最大美学值。
#include<bits/stdc++.h> using namespace std; const int maxn=1e6+100; int n; int dp[maxn]; int a[maxn]; int b[maxn]; int c[maxn]; int w[maxn];//表示 int v[maxn];//表示拆分后背包的容量 int main () { int h1,m1,h2,m2; scanf("%d:%d %d:%d",&h1,&m1,&h2,&m2); int V=h2*60+m2-h1*60-m1; scanf("%d",&n); for (int i=1;i<=n;i++) { scanf("%d%d%d",&a[i],&b[i],&c[i]); if (!c[i]) c[i]=1e6; } int tot=0; for (int i=1;i<=n;i++) { int tt=1; while (c[i]) { w[++tot]=tt*a[i]; v[tot]=tt*b[i]; c[i]-=tt; tt<<=1; if (c[i]<tt) { w[++tot]=a[i]*c[i]; v[tot]=b[i]*c[i]; break; } } } for (int i=1;i<=tot;i++) for (int j=V;j>=w[i];j--) dp[j]=max(dp[j],dp[j-w[i]]+v[i]); printf("%d\n",dp[V]); }