P1833 樱花
爱与愁大神后院里种了n 棵樱花树,每棵都有美学值
爱与愁大神在每天上学前都会来赏花。爱与愁大神可是生物学霸,他懂得如何欣赏樱花:
一种樱花树看一遍过,一种樱花树最多看,一种樱花树可以看无数遍。
但是看每棵樱花树都有一定的时间 。爱与愁大神离去上学的时间只剩下一小会儿了。求解看哪几棵樱花树能使美学值最高且爱与愁大神能准时(或提早)去上学
1. 混合背包问题
int maxval(int v,vector<int>&c,vector<int>&w,vector<int>&cnt){
int n = c.size();
vector<int> dp(v+1);
function<void(int,int)> ZeroOnePack = [&](int cost,int weight){ //0-1背包
for(int j=v;j>=weight;j--)
dp[j] = max(dp[j],dp[j-weight]+cost);
};
function<void((int,int))> CompletePack = [&](int cost,int weight){//完全背包
for(int j=weight;j<=v;j++)
dp[j] = max(dp[j],dp[j-weight]+cost);
};
function<void((int,int,int))> MutiplePack = [&](int cost,int weight,int cnt){//多重背包
if(cnt==0||weight*cnt>=v){ //如果质量超过上限,相当于无限个
CompletePack(cost,weight);
return;
}
int k = 1;
while(k<cnt){
ZeroOnePack(k*cost,k*weight);
cnt-=k;
k*=2;
}
ZeroOnePack(cnt*cost,cnt*weight);
};
int res = 0;
for(int i=0;i<n;i++)//遍历n中树
MutiplePack(w[i],c[i],cnt[i]);
for(int j=0;j<=v;j++)
res = max(res,dp[j]);
return res;
}
int time_trans(string time){
stringstream ss(time);
int hours, minutes;
char delimiter;
ss >> hours >> delimiter >>noskipws >> minutes;
return hours*60 + minutes;
}
int main()
{
string start,end;
int v; int n;
cin>>start>>end>>n;
v = time_trans(end)-time_trans(start);
vector<int> c(n);
vector<int> w(n);
vector<int> cnt(n);
for(int i=0;i<c.size();i++)
cin>>c[i]>>w[i]>>cnt[i];
cout<<maxval(v,c,w,cnt);
return 0;
}