傳送門
題意:有n種物品,每種拿一個都消耗。有的只能拿一個,有的最多拿個,有的可以拿無數個(每種物品可拿次)。每種物品的價值是,揹包容量是,求能獲得的最大價值。
思路:
這題就是01揹包+多重揹包+完全揹包。
代碼:
#include<bits/stdc++.h>
using namespace std;
const int maxn=10000;
int dp[1003];//前:第幾種物品 後:所裝多少
int t[maxn+2],c[maxn+2],p[maxn+2];
int m;//全局變量:總時間(揹包容量)
void completepack(int i,int cost,int weight){
for(int j=0;j<=m;j++){
if(j>=cost)dp[j]=max(dp[j],dp[j-cost]+weight);
}
}
void zeroonepack(int i,int cost,int weight){
for(int j=m;j>=0;j--){
if(j>=cost)
dp[j]=max(dp[j],dp[j-cost]+weight);
}
}
void multiplepack(int i,int cost,int weight,int amount){
if(cost*amount>=m){
completepack(i,cost,weight);
return;
}
int k=1;
while(k<amount){
zeroonepack(i,k*cost,k*weight);
amount-=k;
k*=2;
}
zeroonepack(i,amount*cost,amount*weight);
}
int main(){
int h1,m1,h2,m2,n;
scanf("%d:%d %d:%d %d",&h1,&m1,&h2,&m2,&n);
for(int i=1;i<=n;i++)scanf("%d%d%d",&t[i],&c[i],&p[i]);
int mx=m2-m1;
int hx=(h2-h1)*60;
if(mx<0)hx=(h2-h1-1)*60;
if(mx<0)mx=60-m1+m2;
m=hx+mx;
for(int i=1;i<=n;i++){
if(p[i]==0)completepack(i,t[i],c[i]);
else multiplepack(i,t[i],c[i],p[i]);
}
printf("%d\n",dp[m]);
}