1. 程式人生 > 實用技巧 >P1833 櫻花(二進位制優化揹包)

P1833 櫻花(二進位制優化揹包)

題目背景

《愛與愁的故事第四彈·plant》第一章。

題目描述

愛與愁大神後院裡種了nn棵櫻花樹,每棵都有美學值C_iCi。愛與愁大神在每天上學前都會來賞花。愛與愁大神可是生物學霸,他懂得如何欣賞櫻花:一種櫻花樹看一遍過,一種櫻花樹最多看A_iAi遍,一種櫻花樹可以看無數遍。但是看每棵櫻花樹都有一定的時間T_iTi。愛與愁大神離去上學的時間只剩下一小會兒了。求解看哪幾棵櫻花樹能使美學值最高且愛與愁大神能準時(或提早)去上學。

輸入格式

n+1n+1行:

11行:現在時間T_sTs(幾時:幾分),去上學的時間T_eTe(幾時:幾分),愛與愁大神院子裡有幾棵櫻花樹nn。這裡的T_sTsT_eTe格式為:hh:mm

,其中0 \leq hh \leq 230hh23,0 \leq mm \leq 590mm59,且hh,mm,nhh,mm,n均為正整數。

22行到第n+1n+1行,每行三個正整數:看完第ii棵樹的耗費時間T_iTi,第ii棵樹的美學值C_iCi,看第ii棵樹的次數P_iPiP_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]); }