P1833 櫻花(二進位制優化揹包)
阿新 • • 發佈:2020-08-09
題目背景
《愛與愁的故事第四彈·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]); }