混合背包
混合背包就是指,既有01背包,完全背包,多重背包。
解法很简单,就是对第二层for循环分情况讨论。
直接来题吧
此处多重背包使用二进制优化算法,当然也可以使用单调队列进行优化
详见 https://www.cnblogs.com/kingbuffalo/p/16285929.html
题:https://www.luogu.com.cn/problem/P1833
ac代码如下
#define NMAX 1005
int dp[NMAX];
int main(){
int sh,sm;
int eh,em;
int n;
scanf("%d:%d",&sh,&sm);
scanf("%d:%d",&eh,&em);
scanf("%d",&n);
int tm = (eh-sh) * 60 + em-sm;
int t,c,p;
for(int i=0;i<n;++i){
scanf("%d%d%d",&t,&c,&p);
if ( p == 0 ){
for(int j=t;j<=tm;++j){
dp[j] = max(dp[j],dp[j-t]+c);
}
}else if ( p == 1 ){
for(int j=tm;j>=t;--j){
dp[j] = max(dp[j],dp[j-t]+c);
}
}else{
//多重背包使用二进制优化,一般情况下过得了。
int times = 1;
while(p>=times){
for(int j=tm;j>=t*times;--j){
dp[j] = max(dp[j],dp[j-t*times]+times*c);
}
p-=times;
times *= 2;
}
if ( p ){
for(int j=tm;j>=t*p;--j){
dp[j] = max(dp[j],dp[j-t*p]+c*p);
}
}
}
}
printf("%d\n",dp[tm]);
return 0;
}